tags:

views:

1662

answers:

9

I've had a hard time understanding the difference between composition and aggregation in UML. Can someone please offer me a good compare and contrast between them? I'd also love to learn to recognize the difference between them in code and/or to see a short software/code example.

Edit: Part of the reason why I ask is because of a reverse documentation activity that we're doing at work. We have written the code, but we need to go back and create class diagrams for the code. We'd just like to capture the associations properly.

+2  A: 

You can find a good explanation here.

Otávio Décio
+8  A: 

Composition implies that the child objects share a lifespan with the parent. Aggregation doesn't. For example, a chess board is composed of chess squares - the chess squares don't really exist without the board. However, a car is an aggregation of parts - a car exhaust is still a car exhaust if it's not part of a car at the time.

David M
+15  A: 

The distinction between aggregation and composition depends on context.

Take the car example mentioned in another answer - yes, it is true that a car exhaust can stand "on its own" so may not be in composition with a car - but it depends on the application. If you build an application that actually has to deal with stand alone car exhausts (a car shop management application?), aggregation would be your choice. But if this is a simple racing game and the car exhaust only serves as part of a car - well, composition would be quite fine.

Chess board? Same problem. A chess piece doesn't exist without a chess board only in certain applications. In others (like that of a toy manufacturer), a chess piece can surely not be composed into a chess board.

Things get even worse when trying to map composition/aggregation to your favorite programming language. In some languages, the difference can be easier to notice ("by reference" vs. "by value", when things are simple) but in others may not exist at all.

And one last word of advice? Don't waste too much time on this issue. It isn't worth it. The distinction is hardly useful in practice (even if you have a completely clear "composition", you may still want to implement it as an aggregation due to technical reasons - for example, caching).

Hexagon
I said chess square rather than chess piece, but all valid points.
David M
Hexagon, you've identified issues that make me go back and forth between agg vs. comp. I'll try to keep the "it depends" in mind.
Dopyiii
I definitely take issue with the "It isn't worth it" mindset. If you don't think through who "owns" an object and is responsible for it's lifespan, you'll get very crappy code related to object CRUD, particularly cleanup, with Null pointers flying around as object hierarchies are left in bad states.
Chris Kessel
Object ownership is important, but I'm not certain it has much to do with aggregation/composition. Even if something is composed within something else, a pointer/reference to it may still be passed to others. And when the composing object dies, something still has to be done.
Hexagon
Chess pieces / chess squares - point taken. I can still come up with an example where a chess *square* isn't a composition, but this is harder...
Hexagon
Yes, you shouldn't waste too much time on this issue: UML is an OOA/OOD language; Aggregation/Composition is usually a decision best deferred until OOP. If you try to put too much detail into your UML models, you risk analysis paralysis.
chimp
+7  A: 

The example I learned was fingers to the hand. Your hand is composed of fingers. It owns them. If the hand dies, the fingers die. You can't "aggregate" fingers. You can't just go grab extra fingers and attach and detach them from your hand at will.

The value here, from a design viewpoint, is often related to object lifespan as another poster said. Say you have a Customer and they have an Account. That Account is a "composed" object of the customer (at least, in most contexts I can think of). If you delete the Customer, the Account has no value on it's own so it would be deleted as well. The reverse is often true on object creation. Since an Account only has meaning in the context of a Customer, you'd have Account creation occur as part of Customer creation (or, if you do it lazily, it'd be part of some Customer transaction).

It's useful in design to think about what objects own (compose) other objects vs. ones that just reference (aggregate) other objects. It can help determine where the responsibility lies for object creation/cleanup/updates.

As far as in the code, it's often hard to tell. Most everything in code is an object reference so it may not be obvious whether the referenced object is composed (owned) or aggregated.

Chris Kessel
+2  A: 

In code terms, composition usually suggests that the containing object is responsible for creating instances of the component*, and the containing object holds the only long-lived references to it. So if the parent object gets de-referenced and garbage-collected, so will the child.

so this code...

Class Order
   private Collection<LineItem> items;
   ...
   void addOrderLine(Item sku, int quantity){
         items.add(new LineItem(sku, quantity));
   }
}

suggests that LineItem is a component of Order - LineItems have no existence outside of their containing order. But the Item objects aren't constructed in the order - they're passed in as needed, and continue to exist, even if the shop has no orders. so they're associated, rather than components.

* n.b. the container is responsible for instanciating the component, but it might not actually call new...() itself - this being java, there's usually a factory or two to go through first!

Chris May
A: 

I believe (I remember reading about it somewhere) aggregation was dropped in UML2.0

I just looked for some more details on this and find that "the notation for aggregation has been dropped from UML 2.0." and that "Aggregation can formally always be substituted by an Association." But the site where I found this info is... well... But first time I read about it in some book, so real stuff :)

So stop drawing hollow diamonds...

Peter Perháč
At the bottom of that link, there's this entry though: "To clear the confusion, I e-mailed the author of The Object Primer, Scott Ambler, for clarification. He said that aggregation is back in UML 2.0 due to significant complaining within the community. Thanks."So, start drawing them again...
Dopyiii
+1  A: 

The conceptual illustrations provided in other answers are useful, but I'd like to share another point I've found helpful.

I've gotten some mileage out of UML for code generation, for source code or DDL for relational database. There, I have used composition to indicate that a table has a non-nullable foreign key (in the database), and a non-nullable "parent" (and often "final") object, in my code. I use aggregation where I intend a record or object to be able to exist as an "orphan", not attached to any parent object, or to be "adopted" by a different parent object.

In other words, I've used the composition notation as a shorthand to imply some extra constraints that might be needed when writing code for the model.

erickson
A: 

The example that I like: Composition: Water is a part-of a Pond. (Pond is a composition of water.) Aggregation: Pond has ducks and fish (Pond aggregates ducks and fish)

As you can see I have bolded "part-of" and "has", as these 2 phrases can typically point to what kind of a connection exists between the classes.

But as pointed out by others, many times whether the connection is a composition or an aggregation depends on the application.

Rajah
+2  A: 

Explained here with an example Difference between Aggregation and Composition

vsingh