Composition and aggregation: what are the differences and how to use?

In object orientation it is common for objects of a certain class to have references to one or more objects of other classes. A very simple example is an object of a Class Pedido that has reference to a list of Itens, so that each object of that type has reference to several objects of another type.

It happens that in some cases they call this composition and in other cases they call this aggregation. Researching read what composition is when one of the objects do not exist independently of the other and aggregation is when the two can exist independently. Is that all?

Even if that's it, I still can't identify what the implications of it are in practice. Basically, in both cases it is enough to have a property on the object whose type is the class of the other type. It does not have in code a difference between aggregation and composition, so what are the utilities of differentiating these two cases and what is the difference of these two approaches in the practice?

Author: SomeDeveloper, 2014-07-16

4 answers

The difference between composition and aggregation is related to the existence of objects. This difference is not addressed by programming languages that follow the object-oriented paradigm (at least not the conventional ones: java, C#, c++).

Every time we have composition, it means that the part does not exist without the whole.

Every time we have aggregation, it means that the part can be shared between multiple objects .

Guideline a objects or UML?

Aggregation behavior does not belong exclusively to the object-oriented paradigm. We have the same behavior in the imperative paradigm. This is the case with structures in C. see an example:

struct Person
{
    int age;
    char *name;
    enum { male, female } sex;
};

age, name, and sex make up the type Person

struct bintree
{
    struct bintree *left, *right;
    // some data
};

bintree is composed of left and right, which are Bintree . Reflective composition.

See the concept of composition described in several languages that are not object-oriented in wikipedia .

Types of association in UML

When we talk about aggregation and composition we are talking about special cases of types of association between classes. There are, in UML, associations: simple, aggregation, generalization, dependence, realization (and there must be others that I do not remember now).

The association Type aggregation can be classified basically in two ways: shared (or reflective) composition and aggregation.

Aggregations

These relationship types are so named because they add value to the related object. This is a specialized type of association that allows us to look at the relationship between objects as: whole/part.

Whole / part means that one side of the Association (a class) is called whole and the other side is called Part, since the part allows us to think that: a part is contained not whole .

Composition (or composition aggregation)

Every time we say that the relationship between two classes is composition we are saying that one of these classes (the part) is contained in the other (the whole) and the part does not live/does not exist without the whole.

So every time we destroy the whole, the part that is unique and exclusive of the whole goes together. For this reason some say that: part is contained not all. When you throw the whole thing away, the part was inside and goes along.

Aggregation (or shared aggregation)

This is also a whole/part relationship, however, in this case we say that the part is shared by others (so shared aggregation). This means that the part of a type A is contained in a type B, when it has an aggregation relationship between them, however, that same part A does not exist only for to compose B, this part can aggregate other types.

Summarizing

We have established what compositional and shared aggregations are, now that the names make sense we can exemplify as follows:

  • composition (composition aggregation)

It is necessary that there is at least one item on an invoice for the invoice to exist.

Logo : NotaFiscal is composed of ItemNotaFiscal.

  • aggregation (shared aggregation)

If I have a team registration system, I need multiple people to add teams, so each person can add one team, no team, or multiple teams. The person is independent of the team, but adds value to it.

Logo : Time is aggregated per person.

There is no difference in implementation and yes in behavior

In both the relationship type there is no difference at the time of implementation, see an example in C#:

Composition

class NotaFiscal: IDisposable {
    IList<ItemNotaFiscal> Itens {get;set;}
}

class ItemNotaFiscal: IDisposable { ... }

Aggregation

class Time {
    IList<Pessoa> Integrantes {get;set;}
}

class Pessoa {}

However, the semantic behaviors of associations must be present as to existence. For composition, for example, we could force that every time a note is created, a new list of ItemNotaFiscal must be created. And every time the invoice is erased, the items must be destroy.

class NotaFiscal {
    IList<ItemNotaFiscal> Itens {get;set;}
    NotaFiscal(){
        // Cria lista nova
        Itens = new List<ItemNotaFiscal>();
    }

    void Dispose() {
        foreach(var item in Itens){
            item.Dispose();
        }
    }
}

Thus, the items will be destroyed along with the invoice.

For aggregation it would not be necessary these treatment of creation and destruction of objects. Since the parts can be shared.

Aggregations and multiplicity are different

Many think that every time there is an aggregation / composition we will have a list/array of the parts , however, what tells us if we will have more than one type associated is the multiplicity and not the type of association. Regardless of the type of association, the multiplicity can be: 0.1,* or n..m. So every time an association is 1 to 1, we don't have lists on either side.

See an example:

Composition is not multiplicity

class Carro
{
    Motor UnicoEExclusivoMotor {get;set;}
}

class Motor{}

In this case, Motor is unique and exclusive to Carro, and every time Carro is destroyed, Motor will be destroyed as well.

This deception occurs because most of the time in which an object it is related to a collection of other objects, this association expresses one of the types of aggregation. Aggregation associations where no collections occur are unusual because of this.

Conclusion

Aggregation or composition are type of relationship between two objects/types. Each of the types of association is related to the behavior between objects and the existence of these according to the whole/part concept.

Aggregations have nothing to do with multiplicity. Although, most often, objects associated with a collection of other objects Express, in their relations, an aggregation behavior.

 36
Author: anmaia, 2014-11-16 18:33:38

The difference is only conceptual.

Aggregation

Is when an object has other objects, it does not depend on those objects to exist.

Example:

aggregation

A drawer may contain socks, but the drawer is not made of socks. That is, even without socks The Drawer will still exist.

Composition

Is when an object is formed by other objects. That is, its parts make it up, without them the object does not exist.

Example:

composition

A computer consists of its components, such as Motherboard, enclosure, hd, memory, video card, etc. Without all these parts there is no computer according to the diagram representation. Therefore, in our diagram the computer is a concept, because concretely it is composed of a set of different components.

What changes then?

As I said at the beginning, the difference is only conceptual. Anyone who looks at your class diagram will easily understand what your system is modeling, and that is the intention of UML diagrams, a visual representation of your system. Already at the time of implementation, both the aggregation and composition code may well be written in the same way.

 25
Author: Math, 2020-06-11 14:45:34

In fact, there are no immediately visible practical implications of treating composition and aggregation as one thing. Personally, I never cared about that distinction. However, knowing whether or not a particular property may exist as an independent entity can have an impact on how you model your system, so it is important that you have - albeit only in your mind - this distinction.

Consider the case of composition. In your example, every item belongs to a order, and does not exist outside the context of an order. maybe it was possible to move an item from one order to another, but in practice this does not make much sense. In this way, we have some implications:

  • a Class Item can have a reference to its Pedido. If it does, that reference would not accept null values;
  • the constructor of Item should receive a mandatory parameter specifying which Pedido it belongs to (either to assign the property mentioned above, whether for other purposes). It makes no sense to create an object of Item without knowing what the corresponding object Pedido is;
  • the Pedido class may have methods to list its items, reorder them, add or remove items, etc, but this must be done consistently with the composition rules:
    • if the constructor of Item is public, creating the item should automatically add it to the order. In this case, the Class Pedido would have no methods to " add" - since this is done simply by instantiating the Class Item;
    • otherwise, the Pedido is the only one that could create items - acting as a Factory for them.
    • when removing an item from an order, it must be deleted completely (or marked as such, becoming unusable).
  • finally, when implementing the persistence of these objects, it is important to ensure that items do not exist without requests (e.g. in a database, the foreign key from item to pedido would be " non - nullable ").

Already in the case of aggregation, the API would be different. If we have for example a class Funcionario which in turn belongs to a Departamento. At first, we could have employees without a fixed department, or maybe employees moving from one department to another. In this case, the implications would be as follows:

  • a class Funcionario can have a reference to its Departamento. If you have, this reference must accept null values;
  • the Class Funcionario must have at least one parameterless constructor for Departamento. And constructors that receive this parameter must accept a NULL value. For in this case it makes sense to create an object of Funcionario without a corresponding object Departamento;
  • the Departamento class can have methods to list, append, remove, etc, but this must be done consistently with aggregation:
    • methods to add should receive objects Funcionario points; these methods would then be responsible for assigning the employee to the department and, if necessary, removing him from his previous department if he exists (or refusing to insert him, as the case may be);
    • methods to remove should then put the employee in a "no department" state, but leave him" alive " (i.e. without deleting the object, making it possible for it to be used and/or reinserted in a different department).
    • when implementing persistence of these objects, employees without departments should be allowed (e.g. in a database, the foreign key of funcionario to departamento would be nullable ).

That is, ultimately knowing if you are dealing with an aggregation or compositing case ends up having an impact on your data modeling and API. In the classes themselves, the biggest difference is not in their attributes but in their operations - since it is important to create them from according to what is valid according to your logic. It would be possible, at first, to create a "frankenstein" Code - mixing composition with aggregation-and the compiler would not stop you, but that does not mean that this would be a good and valid design.

 10
Author: mgibsonbr, 2014-07-17 00:04:08

Trying to be pretty succinct:

In aggregation, an object A is referenced, or" called " within another object B. That is, you create two objects A and B and one attribute of B is object a (one is part of the other). But for that to happen, the two have to exist, independent of each other. For this Independence (coexistence), they say that "the part can live without the whole". What does that mean? I said one is part of the other, right? So A is the part. And B is the whole. As the two already existed at first, they have no dependence on each other.

Already in the composition, a class is instantiated, generating object A, at the time of defining an attribute of another object B. That is, Object A is created during the definition of an attribute of B. Therefore, A, which is part, will only exist if B exists. Therefore, we can say that " the part does not exist without the whole."

Now, How does this apply in practice?

Example of aggregation: let's say I create the owner class and the cat class. Now I create a cat object and an owner object. Both exist. Owner has an adopt method(pet), in which he adopts a cat. The function creates an attribute for owner who receives a cat. If I put it as an owner's argument.adopt (pet) the cat object that was created, owner now happens to have the cat as one of its attributes. And this is exactly the same cat that was raised. But if owner ceases to exist, the cat continues to exist normally, because it already existed before.

Example of Composition: now let's say I create the person class and the address class. I create the person object. Do you agree with me that it does not make much sense I create an address object, if it is not associated with anyone? If I were to create an address object and it was assigned to the person, it would be hers and only hers (with the exception of whoever lived with her). So it would make more sense I create an address attribute within the person class, which will receive parameters relating to specific address information from each person object that is created. If the person object is deleted, it makes no sense to have an address object. And since it was set inside person, it will be deleted in the same way.

 0
Author: redSquare, 2019-12-12 22:28:20