I've recently spent a good deal of time performing detailed UML designs of various SW components that I have since written. Looking back on what I have recently finished and comparing that to when I first learned UML, I see that I now almost strictly use Aggregation and Composition relationships, and have virtually abandoned "vanilla" non-directed/directed relationships. I still of course use Generalizations and Realizations, but these are distinctly different than those above and are not considered part of this question.
It seems to me that Aggregation/Composition implies the same meaning of "vanilla" associations, and more. Aggregation and Composition naturally imply a direction, and any modern UML program will still allow you to define multiplicity on an Aggregation/Composition relationship and apply a verb to the relationship as well. At that point, I see little purpose to vanilla associations.
I understand some people have difficulty understanding the difference between Aggregation and Composition. Early on, I had a bit of difficult grasping how they differ, and I believe that confusion was part of the reason I used vanilla associations. I'm at the point now where I see little or no use for vanilla associations, and actually dislike seeing them used as I believe they leave some things up for question (particularly a strong or weak lifecycle relationship between two objects). I believe vanilla associations' only practical use is when your understanding of the problem at hand isn't yet developed enough to determine the life cycle difference between aggregation and composition. In such a case it is better to atleast show that the relationship exists and you can then come back and change it appropriately when you have a better understanding of the problem at hand.
Long story short, I believe the vast majority of the time that people use vanilla associations, they could be more accurately described as an aggregation, and sometimes as a composition. Am I terribly wrong in my belief? Am I missing something? Let me hear it!
In fact, most cases of associations in UML class models are neither aggregations nor compositions. For instance, the association between the classes
Publisher
andBook
for assigning the books published by a publisher to this publisher is neither an aggregation nor a composition because the books published by a publisher are not parts or components of this publisher.An aggregation is a special form of association with the intended meaning of a part-whole-relationship, but without a precise semantics (the UML spec says: "Precise semantics of shared aggregation varies by application area and modeler"). For instance, we can model an aggregation between the classes
Car
andEngine
and between the classesCourse
andLecture
since an engine is part of a car and a lecture is part of a course.A composition (also called "composite aggregation" in the UML spec) is a special form of aggregation, where a component instance is part of at most one aggregate instance at a time (that is, it cannot be shared between several aggregates). This means that the aggregation between
Car
andEngine
is a composition (because an engine cannot be shared between two cars at the same time), while an aggregation betweenCourse
andLecture
is not necessarily a composition since a lecture can be shared among two courses (e.g. a database management course and a software engineering course could share a lecture on UML). This implies that the multiplicity of a composition's association end at the aggregate side is either 1or 0..1, while it may be also * in the case of a non-composite aggregation.In addition to this main characteristics of a composition (to have exclusive parts), a composition may also come with a life-cycle dependency between an aggregate and its components implying that when an aggregate is deleted, all of its parts are deleted with it. However, this only applies to some cases of composition, and not to others, and it is therefore not a defining characteristic. The UML spec states: "A part may be removed from a composite instance before the composite instance is deleted, and thus not be deleted as part of the composite instance." In our example of the Car-Engine composition, it's clearly the case that the engine can be removed from the car before the car is destroyed, in which case the engine is not destroyed and can be re-used.
Vanilla Associations, Aggregration and Compositions are sometimes explained with the following semantics:
mostly differentation of aggregation and composition go around the question "if the master object is gone - what happens to the part objects?".
So the idea is to have some integrity constraint like "on delete cascade" be described using a differentiation in using one of the three options. UML has three different symbols for this
The issue with these three options is that the semantics are not precise enough for real life situations, especially if you look at situations that change over time
E.g. Trying to answer the simple question "How many tire-wheels does my car have?" Will lead to different answers:
How many of these wheels will be gone when the car is gone? If you try to model this situation with the three symbols UML is offering you'll end up with a lot of discussion and negotiation what your model really means. I think it is far better never to use aggegation and composition symbols but instead always describe the association semantics as precisely as possible with a few lines of text. This way you can make it clear to the people reading your model what you really want. I think it is even o.k. to write "A car is a composition of parts which includes the wheels ...."
But now you are not using a composition symbol but are really referencing the act of composing something.
see also http://de.wikipedia.org/wiki/Assoziation_%28UML%29#Aggregation_und_Komposition (german)
On a class diagram, you are thinking of the static relationships between classes. You probably don't really need to think about the behavioural aspects of those relationships on the class diagram, it just muddies the waters and is evidence of over-analysis. (IMHO of course)
Both aggregations and compositions imply that a participant in the relationship "dominates" the other (in compositions the dominance is stronger), while normal associations don't have this implication. Therefore, I use normal associations when both participants have the same importance in the relationship
You have hit on the head when you say, 'vanilla associations' only practical use is when your understanding of the problem at hand isn't yet developed enough to determine the life cycle difference and show that the relationship exists and you can then come back and change it appropriately when you have a better understanding of the problem at hand.
The UML Meta-Model defines Aggregation and Composition as extensions of Association. An Association can be considered an unrefined relationship between domain objects, in the same way that a Domain object is an unrefined Class. I typically use simple Associations at the Domain Modelling stage and refine it into either Composition or Aggregation as appropriate when I resolve the detailed Class Model.