96

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.

reinierpost
  • 8,425
  • 1
  • 38
  • 70
Dave
  • 4,050
  • 6
  • 30
  • 35
  • Also see [implementation-difference-between-aggregation-and-composition-in-java](http://stackoverflow.com/questions/11881552/) – nawfal Oct 03 '13 at 10:53
  • Please, check a code-based example at: http://stackoverflow.com/questions/731802/what-is-the-difference-between-composition-and-association-relationship/23464244#23464244 – Almir Campos May 05 '14 at 03:18
  • UML 2.5 has clarified the difference. See the box on p. 110. So I'm voting to re-open this. – qwerty_so Jan 09 '19 at 09:06
  • No, UML 2.5 did not clarify the definition of composition, rather it has remained ambiguous about it, since they also say "A part object may be removed from a composite object before the composite object is deleted, and thus not be deleted as part of the composite object." See my answer below (https://stackoverflow.com/questions/734891/aggregation-versus-composition/27889087#27889087) where I have tried to clarify the meaning of composition. Please upvote my answer to show that in SO, the correct answer wins in the end :-) [or downvote all incorrect answers] – Gerd Wagner Nov 11 '19 at 22:21
  • UML is seriously broken, crippled, completely unfit to be a Standard.  1) All the definitions are vague.  2) It provides nothing to compose/decompose the whole project (whereas previous Process Modelling methods do). Modularity is completely lost.  3) Its Aggregation is vague, it means different things to different people.  4) People need Composition, which UML does not provide, so they misuse Aggregation to obtain a fraction of it.  99) the list is endless. – PerformanceDBA Jun 07 '21 at 00:28
  • @GerdWagner  Re *in SO, the correct answer wins in the end*. No.  The mountain of consistent evidence is, in SO, the most popular answer wins, the correct answer gets buried. The notion of an Authority; an objectively correct answer, is rejected. You and I are fighting an uphill battle against populism. – PerformanceDBA Jun 07 '21 at 00:31
  • 1
    @PerformanceDBA I'm afraid you are right, but let's still keep fighting :-) – Gerd Wagner Jun 08 '21 at 17:53
  • @GerdWagner  Not me. I gave up after the fiasco last year. Then they started censoring my Answers, that killed any remaining interest. Now I only keep my old Answers clean. – PerformanceDBA Jun 09 '21 at 04:00

12 Answers12

104

As a rule of thumb: enter image description here

class Person {
    private Heart heart;
    private List<Hand> hands;
}

class City {
    private List<Tree> trees;
    private List<Car> cars
}

In composition (Person, Heart, Hand), "sub objects" (Heart, Hand) will be destroyed as soon as Person is destroyed.

In aggregation (City, Tree, Car) "sub objects" (Tree, Car) will NOT be destroyed when City is destroyed.

The bottom line is, composition stresses on mutual existence, and in aggregation, this property is NOT required.

Hoa Nguyen
  • 13,452
  • 11
  • 45
  • 44
93

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
  • 6,845
  • 2
  • 24
  • 16
  • 1
    I said chess square rather than chess piece, but all valid points. – David M Apr 09 '09 at 16:39
  • 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. – Dave Apr 09 '09 at 16:42
  • 2
    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 Apr 09 '09 at 17:23
  • 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 Apr 09 '09 at 20:57
  • 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 Apr 09 '09 at 20:58
  • 10
    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 Apr 14 '09 at 04:21
  • 15
    +1 for "don't waste too much time on this". That's what I needed to hear! – Ronnie May 18 '12 at 15:31
  • 10
    "don't waste too much time on this" Why don't interviewers understand this? – titogeo Jul 18 '12 at 09:26
  • 1
    @gTito It makes them feel feel smarter than you? http://www.huffingtonpost.com/2013/06/20/google-brainteasers_n_3472406.html – Fuhrmanator Jul 09 '13 at 21:39
  • The best answer ever stated... excelente! – Victor Jul 09 '14 at 00:29
  • 1
    UML 2.5 has clarified the difference. See the box on p. 110. – qwerty_so Jan 09 '19 at 09:04
  • About the box that @ThomasKilian is talking about: https://www.omg.org/cgi-bin/doc?formal/15-03-01.pdf <> – campisano Feb 17 '19 at 02:11
66

Composition and Aggregation are types of associations. They are very closely related and in terms of programming there does not appear to be much of a difference between the two. I will try to explain the difference between these two by java code examples

Aggregation: The object exists outside the other, is created outside, so it is passed as an argument (for example) to the constructor. Ex: People – car. The car is created in a different context and then becomes a person property.

// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer(HttpListener listener, RequestProcessor processor) {
    this.listener = listener;
    this.processor = processor;
  }
}

Composition: The object only exists, or only makes sense inside the other, as a part of the other. Ex: People – heart. You don’t create a heart and then pass it to a person. Instead, the heart is created when the human is created.

// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer() {
    this.listener = new HttpListener(80);
    this.processor = new RequestProcessor(“/www/root”);
  }
}

Explained here with an example Difference between Aggregation and Composition

Anchith Acharya
  • 369
  • 1
  • 4
  • 16
vsingh
  • 6,365
  • 3
  • 53
  • 57
  • 8
    One of the best answer so far. Neat :) – Rohit Singh Nov 02 '16 at 04:16
  • 7
    The best Java code example of showing when object can exist with(composition) or without(aggregation) other objects. – Michał Dobi Dobrzański Jun 11 '17 at 06:22
  • please, I want to know do we should use final for Composition or not ? – khalid tounoussi Nov 18 '19 at 15:54
  • −1. The difference between *composition* and *aggregation* has nothing to do with whether the part can exist only inside the whole or not (an engine can exist outside a car, yet their relation is not an aggregation but a composition). It has to do with whether the part is unique or shared for different wholes, i.e. with whether the upper bound of the multiplicity of the wholes related to the part is 1 or not, i.e. with whether the part–whole relation is [functional](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations) (right-unique) or not. See Gerd Wagner’s answer. – Géry Ogam Dec 28 '20 at 02:21
  • This was great that fully recovers all questions in my head! – Fatih Ersoy Jun 19 '21 at 22:44
36

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
  • 71,481
  • 13
  • 158
  • 186
19

It's amazing how much confusion exists about the distinction between the part–whole association concepts aggregation and composition. The main problem is the widespread misunderstanding (even among expert software developers and among the authors of UML) that the concept of composition implies a life-cycle dependency between the whole and its parts such that the parts cannot exist without the whole. But this view ignores the fact that there are also cases of part–whole associations with non-shareable parts where the parts can be detached from, and survive the destruction of, the whole.

In the UML specification document, the definition of the term "composition" has always implied non-shareable parts, but it has not been clear what is the defining characteristic of "composition", and what is merely an optional characteristic. Even in the new version (as of 2015), UML 2.5, after an attempt to improve the definition of the term "composition", it remains still ambiguous and doesn't provide any guidance how to model part–whole associations with non-shareable parts where the parts can be detached from, and survive the destruction of, the whole as opposed to the case where the parts cannot be detached and are destroyed together with the whole. They say

If a composite object is deleted, all of its part instances that are objects are deleted with it.

But at the same time they also say

A part object may be removed from a composite object before the composite object is deleted, and thus not be deleted as part of the composite object.

This confusion points to an incompleteness of the UML definition, which does not account for lifecycle dependencies between components and composites. It's therefore important to understand how the UML definition can be enhanced by introducing a UML stereotype for <<inseparable>> compositions where components cannot be detached from their composite, and, thus, have to be destroyed whenever their composite is destroyed.

Composition

As Martin Fowler has explained, the main issue for characterizing composition is that "an object can only be the part of one composition relationship". This is also explained in the excellent blog post UML Composition vs Aggregation vs Association by Geert Bellekens. In addition to this defining characteristic of a composition (to have exclusive, or non-shareable, parts), a composition may also come with a life-cycle dependency between the composite and its components. In fact, there are two kinds of such dependencies:

  1. Whenever a component must always be attached to a composite, or, in other words, when it has a mandatory composite, as expressed by the "exactly one" multiplicity at the composite side of the composition line, then it must either be re-used in (or re-attached to) another composite, or destroyed, when its current composite is destroyed. This is exemplified by the composition between Person and Heart, shown in the diagram below. A heart is either destroyed or transplanted to another person, when its owner has died.
  2. Whenever a component cannot be detached from its composite, or, in other words, when it is inseparable, then, and only then, the component has to be destroyed, when its composite is destroyed. An example of such a composition with inseparable parts is the composition between Person and Brain.

Person-Brain-Heart

In summary, life-cycle dependencies only apply to specific cases of composition, but not in general, they are 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 the example of a CarEngine composition, as shown in the following diagram, it's clearly the case that the engine can be detached from the car before the car is destroyed, in which case the engine is not destroyed and can be re-used. This is implied by the zero or one multiplicity at the composite side of the composition line.

enter image description here

The multiplicity of a composition's association end at the composite side is either 1 or 0..1, depending on the fact if components have a mandatory composite (must be attached to a composite) or not. If components are inseparable, this implies that they have a mandatory composite.

Aggregation

An aggregation is another special form of association with the intended meaning of a part–whole relationship, where the parts of a whole can be shared with other wholes. For instance, we can model an aggregation between the classes DegreeProgram and Course, as shown in the following diagram, since a course is part of a degree program and a course can be shared among two or more degree programs (e.g. an engineering degree could share a C programming course with a computer science degree).

enter image description here

However, the concept of an aggregation with shareable parts doesn't mean much, really, so it does not have any implications on the implementation and many developers therefore prefer not to use the white diamond in their class diagrams, but just model a plain association instead. The UML spec says: "Precise semantics of shared aggregation varies by application area and modeler".

The multiplicity of an aggregation's association end at the whole side may be any number (*) because a part may belong to, or shared among, any number of wholes.

Gerd Wagner
  • 5,481
  • 1
  • 22
  • 41
  • 2
    Composition isn't strictly related to lifecycle, but in most real world problems the lifecycle is a primary motivator of whether you'd compose or aggregate. I did hedge in my answer, saying lifecycle is "often" related rather than always related. It's good to note lifecycle isn't required, but stating that view is a "main problem" and wrong (in nice bold font) strikes me as unhelpful and detracts from pointing out the practical usage considerations. – Chris Kessel Jan 15 '15 at 18:18
  • 1
    I strongly disagree. Lifecycle considerations cannot be a "primary motivator of whether you'd compose or aggregate", since you have them in many cases of associations independently of the fact if they represent any kind of part-whole realtionship (aggregation or composition). Whenever an association has an end with a lower bound multiplicity greater than 0, corresponding to a mandatory reference property, you'll get a lifecycle dependency. – Gerd Wagner Jan 20 '15 at 12:30
  • Extremely interesting, especially the heart and brain composition example. To implement a composition with a removable part in C++ (e.g. a `Person` with an `Heart`), I guess a donor’s heart must be transplanted within a recipient only in the donor’s destructor `Person::~Person()`, which implies passing the recipient to the donor before with a method `Person::setRecipient(Person*)`. And to prevent the same heart from being transplanted to multiple recipients (which would make an aggregation instead of a composition), the method `Person::transplant(Heart*)` must be `private`. – Géry Ogam Dec 12 '20 at 14:40
  • One remark though: shouldn’t the heart multiplicity in the person–heart composition be 1..\* instead of \*, the engine multiplicity in the car–engine composition be 1 instead of 0..1, and the course multiplicity in the degree–course aggregation be 1..\* instead of \*? Because a person without a heart, a car without an engine, or a degree without a course does not make sense. I think multiplicity 0 of a part is not possible for a part–whole relationship (aggregation or composition), since the whole is *made of* (exists through) its parts. Multiplicity 0 is only possible for an association. – Géry Ogam Dec 12 '20 at 14:59
  • 1
    @Maggyero: Only if the part is mandatory, a minimum cardinality of 1 is needed. In the case of a person's heart, this is certainly the case and I've corrected the diagram above. But in the case of a car's engine, one may say that a car is still a car, even without an engine. In the case of a degree program, if the diagram represents a domain model, then indeed there should be at least one assigned course. But if i represents a class design model, we may prefer not to require an assigned course. – Gerd Wagner Dec 14 '20 at 12:19
  • Okay thanks. However you corrected the person–heart composition by replacing the heart multiplicity `*` by `1` instead of `1..*`. I am not sure it is correct since I interpreted your previous heart multiplicity `*` as: a person can have many hearts *throughout his life* (but only one brain, which was specified by the brain multiplicity `1`), which made sense. – Géry Ogam Dec 14 '20 at 13:12
  • Such a historical interpretation of constraints is an option, but it's not the standard semantics, which just refers to any given state of an OO system. Now, the model says that both brain and heart are mandatory for a person (in fact, s/he needs exactly one of them), but a heart can be exchanged while a brain cannot. – Gerd Wagner Dec 14 '20 at 16:09
  • @GerdWagner Thanks for the clarification. Couldn’t way express the “inseparable” constraint of the person–brain composition with this UML means: the {readonly} property modifier? – Géry Ogam Dec 16 '20 at 10:04
  • 1
    @Maggyero: That's an interesting question. A {readonly} characterization of the brain association end would mean that the brain assignment cannot be changed, but would it also imply that on destruction of the person the brain cannot be detached, but must be destroyed as well? I don't think so. – Gerd Wagner Dec 16 '20 at 20:53
  • I think you are right, {readonly} is not enough. Is “inseparable” on your diagram a stereotype? – Géry Ogam Dec 16 '20 at 22:32
  • 1
    Yes, I propose to define an “inseparable” stereotype of composite associations and use it for these cases. – Gerd Wagner Dec 17 '20 at 10:21
  • To sum up, the difference between *composite-aggregation* (a.k.a. *composition*) and *shared-aggregation* has to do with whether the part is unique or shared for different wholes, i.e. with whether the upper bound of the multiplicity of the wholes related to the part is 1 or not, i.e. with whether the part–whole relation is [functional](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations) (right-unique) or not. – Géry Ogam Dec 28 '20 at 02:20
19

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
  • 5,583
  • 4
  • 36
  • 55
8

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
  • 670
  • 3
  • 6
0

It's so difficult to do a difference between aggregate relation and composite relation, but I'm going to take some examples, We have a house and rooms, here we have a composite relation, room it's a part of the house , and room life started with house life's and Will finish when house life's finish, room it's a part of the house, we talk about composition, like country and capital, book and pages. For aggregate relation example, take team and players, player can exist without team, and team is a group of players, and player life can started before team life's, if we speak about programming, we can create players and after we Will create team, but for composition no, we create room s inside of house . Composition ----> composite|composing. Aggregation -------> group | element

read
  • 1
0

Let's set the terms. The Aggregation is a metaterm in the UML standard, and means BOTH composition and shared aggregation, simply named shared. To often it is named incorrectly "aggregation". It is BAD, for composition is an aggregation, too. As I understand, you mean "shared".

Further from UML standard:

composite - Indicates that the property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (parts).

So, University to cathedras association is a composition, because cathedra doesn't exist out of University (IMHO)

Precise semantics of shared aggregation varies by application area and modeler.

I.e., all other associations can be drawn as shared aggregations, if you are only following to some principles of yours or of somebody else. Also look here.

Community
  • 1
  • 1
Gangnus
  • 24,044
  • 16
  • 90
  • 149
0

Consider human body parts like kidney, liver, brain. If we try to map concept of composition and aggregation here, it would be like:

Before the advent of body parts transplantation like that of kidney's and liver's, these two body parts were in composition with human body and cannot exist isolation with human body.

But after the advent of body part transplantation, they can be transplanted in another human body, so these parts are in aggregation with human body as their existence in isolation with human body is possible now.

Azfar Niaz
  • 1,516
  • 4
  • 13
  • 21
0

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
  • 265,237
  • 58
  • 395
  • 493
0

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.

Raj Rao
  • 8,872
  • 12
  • 69
  • 83
  • But part-of and has terms confuses sometime. For example, a Person class "has" name, so shows as Person has aggregation relation with name. In fact, it is composition relation. Why? When Person object destroys, so should the name. And the term "name is a part-of person", does not sounds natural. – Asif Shahzad Sep 19 '13 at 19:50