Thursday, May 28, 2009

The UML Class diagram is used to visually describe the problem domain in terms of types of objects (classes) related to each other in different ways.

There are 3 primary inter-objectrelationships: Association, Aggregation, and Composition. Using the right relationship line is important for placing implicit restrictions on the visibility and propagation of changes to the related classes, a matter which plays an important role in understanding and reducing system complexity.

Association

The most abstract way to describe static relationship between classes is using the Association link, which simply states that there is some kind of a link or a dependency between two classes or more.

Weak Association

ClassA may be linked to ClassB in order to show that one of its methods includes parameter of ClassB instance, or returns instance of ClassB.

Strong Association

ClassA may also be linked to ClassB in order to show that it holds a reference to ClassB instance.

Aggregation (Shared Association)

In cases where there’s a part-of relationship between ClassA (whole) and ClassB (part), we can be more specific and use the aggregation link instead of the association link, highlighting that the same ClassB instance can also be aggregated by other classes in the application (therefore aggregation is also known as shared association).

It’s important to note that the aggregation link doesn’t state in any way that ClassA owns ClassB nor that there’s a parent-child relationship (when parent deleted all its child’s are being deleted as a result) between the two. Actually, quite the opposite! The aggregation link is usually used to stress the point that ClassA instance is not the exclusive container of ClassB instance, as in fact the same ClassB instance has another container/s.

Aggregation v.s. Association

The association link can replace the aggregation link in every situation, while aggregation cannot replace association in situations where there’s only a ‘weak link’ between the classes, i.e. ClassA has method/s that contain parameter of ClassB, but ClassA doesn’t hold reference to ClassB instance.

Martin Fowler suggest that the aggregation link should not be used at all because it has no added value and it disturb consistency, Quoting Jim Rumbaugh "Think of it as a modeling placebo".

Composition (Not-Shared Association)

We should be more specific and use the composition link in cases where in addition to the part-of relationship between ClassA and ClassB - there’s a strong lifecycle dependency between the two, meaning that when ClassA is deleted then ClassB is also deleted as a result

The composition link shows that a class (container, whole) has exclusive ownership over other class/s (parts), meaning that the container object and its parts constitute a parent-child/s relationship.

Unlike association and aggregation, when using the composition relationship, the composed class cannot appear as a return type or parameter type of the composite class. Thus, changes to the composed class cannot propagate to the rest of the system. Consequently, usage of composition limits complexity growth as the system grows.

Clarification: It is possible for a class to be composed by more than one class. For example, ClassA may be composed by ClassB and ClassC. However, unlike aggregation, instances of ClassB and ClassC will never share the same ClassA instance. That would violate the propagation of changes principle. ClassB instance will have its own instance of ClassA, and ClassC instance will have its own instance of ClassA.

Measuring system complexity

System complexity can be measured simply by looking at a UML class diagram and evaluating the association, aggregation, and composition relationship lines. The way to measure complexity is to determine how many classes can be affected by changing a particular class. If class A exposes class B, then any given class that uses class A can theoretically be affected by changes to class B. The sum of the number of potentially affected classes for every class in the system is the total system complexity.

Thanks for your explanation, it is much clearar compared to all other sources I read. However, one detail is still confusing. You mention in your explanation of aggregation and composition that one class is or is not exclusive owner of another class. Did you rather mean instances of a specific class? I guess class A and class B can have a composite relationship to class C, if class A and Class B have different instances of class C.

Yes, that's correct. Multiple classes can have a composite relationship with the same class, as long as they don't expose the composed class to the outside world and there's a life-cycle dependency between them.

Really a great explanation, I've never really understood the meaning/semantic of them and where to use them, and u put it very simple!

I still have 2 situations I dodn't understand. So, when using composite, it means an object of class A (the one with the black symbol) stores 1 or more objects of class B, and when that A object is deleted, those B objects are also deleted?

Another question. You talked about weak aggregation where class A has operation that receives parameter or returns object of class B. But what if an operation of class A does some processing using class B (being it static class or object instance)? That operation could call a class C operation, receive a class B object return, use that object internally but its return doesn't involve class B anymore. So, if inside class A's operation there's a use of class B (and therefore if class B is missing we can't compile class A!), will we need to add assossiation from A to B?

To finish the comment, I'd add the information that when we have an assossiation of one-to-many, it will be implemented by adding to class A a collection of class B's objects. It's facultative to explicity put in class A the attribute that will hold that collection or leave it implicit by the assossiation.

I took some time to learn how to implement this kind of model, now I myself like to explicitly show all classes attributes, and leave multiplicity to inform how a class knows about the other. In domain models I use multiplicity to inform how one depends of the other, in database models I use to inform their relational assossiations, and in class models I use to inform if a class relies on the other (it knows about that class and won't compile if the class is missing).

Hikari, the answer for your 1st question is yes - in composition, when the container class is deleted, all the contained objects are deleted as a results.I didn't quite understand your second question. My guess is that you were referring to a case where Class A is weakly associated with Class B, and in Class A internal implementation it get instance of Class C through Class B. In that case, there's a weak association relationship between Class A and Class C - and that should made visible in the UML diagram.

Superb explanation! Have one question regarding association vs aggression. In your example of strong association, you showed its multiplicity 1:1. That means both classes have class members as pointers to each other class. What about 1:* (one to many) association multiplicity? Would it be same as aggregation? Sometimes, I see 0..1:1..*(zero or one to one or many) multiplicity when looking at some relational database models (drawn with UML class diagram) where associations are used to describe relations between parent and child tables (for example, there are tools that allow to generated database schema from class diagram). But if one-to-many association is the same as aggregation then there's a logic conflict: in relation tables, a child table record can hold a reference (parent_id column) to only one parent record. So those associations are more composition style relations. Any thoughts on that?

Some additional notes: aggregation might be considered as many-to-many association relation because both end classes might be used in different related instances, so in some situations, it might be no matter what class is composite and what component - both might be included in each other. On the other hand, one-to-many association might be considered as composition .... but nop, because association does not restrict the same child object be assigned with another parent object. Actually, I do very agree with Martin Fowler about aggregation link should not be used at all because it adds ambiguity, because the same might be achieved with association with multiplicity one-to-many.

The multiplicity in strong association is a mistake - thanks for bringing this up!

You can have one to many multiplicity for all the link types - Association, aggregation and Composition. Many to many is possible only for association, as whole-part (or parent-child) can only go one way.You also need to remember that with composition, the composed class is only visible to its parent.

a) "The multiplicity in strong association is a mistake" - So, we don't need to put 1:1 multiplicity when modeling strong associations at all? If so then both strong and weak associations will look the same (both will just have association without any multiplicity). How to distinguish them? Maybe I'v missed something in your answer...

b) "You can have one to many multiplicity for all the link types" - why do we need to have that on aggregation and Composition? Composition is for modeling one-to-many relation, and the same is with aggregation.

c) I would like to argue about "Many to many is possible only for association". IMHO aggregation is very similar to many-to-many relation. For example, assume there's an aggregation relation between "part" and "airplane" classes . Then both classes might consist from each other: one part might belong to several airplanes, and airplane might consist of several parts. In relational database wold, that is definite a many-to-many relation. Though maybe we should use many-to-many association in such situations ... ?

What I meant by "multiplicity in strong association is a mistake" is that I shouldn't have drawn 1-1 multiplicity because it's confusing. You can have 1-1 multiplicity in strong association, but it's not a must.

Here's my understanding, In aggregation and composition - you can have 1-1 and 1-many multiplicity. In association (week and strong) - you can have 1-1, 1-many and many-many multiplicity.

Thanks for sharing :) I have just one question,In the post,as I understood, the only difference between Aggregation and Association, technically, is that the Aggregation can't model the Association(case of weak Association), Actually what mentionned as "weak Association" is the UML "Dependency" relation, so if that's the case what's the difference between the Aggregation and Association?

This is a great point others have missed. The "Weak Association" is actually a "Dependency" in UML. The difference between Aggregation and Association is that aggregation uses a conceptual "is part of" relationship. Like a car is made of an engine and doors. If there is no whole-part relationship is just an association. An aggregation is a specific case of association.

Thanks for the great explanation the three primary relationships. I like how you took it and explained it even more. I was still looking up What is a Class Diagram in UML and found this to be pretty helpful as well. Thanks for all of your great work!

Hello, thank you very much for your great article, but I still don't understand the arrow directions. In Association, arrow points from Class A -> Class B, however, in Aggregation, the diamond (which I, who may may be wrong, think is another kind of arrow) points from Class B to Class A. Would you be kindly to explain it to me? How can I decide which direction should arrow / diamond point to when I draw a class diagram?

I guess in Composition you can still return a Composed class-type object in Composite class, when it's read-only or value type? Or Composition strictly says that other objects than Composite class cannot use and see Composed class?

As you mentioned that A and class B can have a composite relationship to class C, if class A and Class B have different instances of class C and as long as they don't expose the composed class to the outside world and there's a life-cycle dependency between them.So if they expose Class C to the other class even though it is created inside Class A or B, then the relationship will be Aggregation ?

Correct. If ClassC is exposed the composition link cannot be used. Exposing an object (via public property) that is deleted by its container is also error prone, as it increases the risk for NULL reference exceptions.

Hi Aviade, Unlike association and aggregation, in the composition relationship, the composed class cannot appear as a return type or parameter type of the composite class, thus changes in the composed class cannot be propagated to the rest of the system.

This is the best and most accurate explanation i could find on internet. Thank you for putting this together. It would be great if you can give some examples on Class Diagrams and ideal design for them.

Hi Aviad,First, thanks a bunch for this useful article, just one doubt about your example of Aggregation: if Wheel and Engine objects were exclusive of Car object, then would it be a Composition relationship?This doubt arises because in some topics about Composition relationships almost always people give a Car-Engine-Wheel example as that kind of relationship.Maybe, all depends about the requirements to consider if Car-Engine-Wheel example would be Aggregation or Composition relationship.