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

Asked

Viewed 67,145 times

43

Object orientation 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 with reference to a list of Itens, in such a way that each such object has reference to several objects of another type.

It turns out that in some cases they call it composition and in other cases they call it aggregation. Researching li that composition is when one of the objects does not exist independent of the other and aggregation is when the two can exist independently. That’s all there is to it?

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

4 answers

36


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

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

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

Object orientation 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 for C-shaped structures. See an example:

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

age, name and sex make up the Person type

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 speak of aggregation and composition We are talking about special cases of types of class association. There are, in UML, associations: simple, aggregation, generalization, dependence, realization (and there must be others that I don’t remember now).

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

Aggregations

These types of relations are so called because they add value to the related object. This is a specialized type of association that allows us to face the relationship between objects as: Whole/Part.

Whole/Part means that one side of the association (a class) is called All and the other side is called Part, since the part allows us to think that: A Part is contained in the All.

Composition (or aggregation of composition)

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

Therefore, every time we destroy the whole, the part that is unique and exclusive of the whole goes together. For this reason no one says that: the part is contained all in all. When you throw the whole out, the part was in and goes along.

Aggregation (or shared aggregation)

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

In short

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

  • Composition (Aggregation of composition)

There must be at least one item in a tax note for the tax note to exist.

Soon: Notafiscal is composed of Itemnotafiscal.

  • Aggregation (shared aggregation)

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

Soon: Time is aggregated by Person.

There is no difference in implementation but in behavior

In both types of relation 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 behaviors semantics associations must be present for their existence. For composition, for example, we could force that every time a note is created, a new list of Itemnotafiscal should be created. And every time the invoice is deleted, the items must be destroyed.

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.

Aggregation would not require such object creation and destruction treatment. Since the parties can be shared.

Aggregations and multiplicity are different

Many think that every time there is an aggregation/composition we will have a list/part array, however, what tells us if we will have more than one associated type is multiplicity and not the kind 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 have no lists on either side.

Take an example:

Composição não é multiplicidade

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

class Motor{}

In that case, the Motor is unique and exclusive to the Carro, and every time Carro is destroyed, the Motor will also be destroyed.

This deception occurs because most often when an object 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.

Completion

Aggregation or composition are a type of relationship between two objects/types. Each of the types of association is related to the behavior between the objects and to their existence 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 relationships, an aggregation behavior.

  • I took the opportunity to write an article on the subject in https://www.anmaia.com.br/posts/composicao-e-agregacao-tem-diferenca

26

The difference is only conceptual.

Aggregation

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

Example:

agregacao

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

Composition

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

Example:

composicao

A Computer is formed by its components, such as motherboard, cabinet, hard drive, memory, video card, etc. Without all these parts there is no Computer according to the representation of the diagram. 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 strikes their eye in 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 code of aggregation and the code of composition may well be written in the same way.

  • 1

    Straightforward!

11

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

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

  • A class Item may have a reference to your Pedido. If so, such reference would not accept null values;
  • The builder of Item should receive a mandatory parameter specifying which Pedido to which it belongs (either to assign the property mentioned above or for other purposes). It makes no sense to create an object of Item without knowing what the object is Pedido correspondent;
  • The class Pedido may have methods to list your items, reorder them, add or remove items, etc., but this should be done in a manner consistent with the rules of composition:
    • If the builder of Item is public, create the item should automatically add it to the order. In this case, the class Pedido would not have methods to "add" - since this is done simply by instantiating the class Item;
    • Otherwise, the Pedido is the only one who could create items - acting as a factory for the same.
    • When removing an item from an order, it should be deleted completely (or marked as such, becoming unusable).
  • Finally, when implementing the persistence of these objects, it is important to ensure that the items do not exist without orders (e.g.: in a database, the foreign key of item for pedido would be "no-nullable").

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 that case, the implications would be as follows::

  • A class Funcionario may have a reference to your Departamento. If so, this reference shall accept null values;
  • The class Funcionario must have at least one constructor without parameter for Departamento. And the constructors that receive this parameter must accept a null value. Because in this case it does make sense to create an object of Funcionario without an object Departamento correspondent;
  • The class Departamento may have methods to list, add, remove, etc., but this should be done consistently with aggregation:
    • Add methods 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 it exists (or refusing its insertion, as the case may be);
    • The methods to remove should then put the employee in a "no department" state, but leaving him "alive" (i.e. without excluding the object, making it possible for it to be used and/or reinserted into a different department).
    • When implementing the persistence of these objects, one should allow employees without a department (e.g.: in a database, the foreign key of funcionario for departamento would be nullable).

That is, at the end of the day, whether you’re dealing with a case of aggregation or composition has 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 according to what is valid according to their logic. It would be possible, at first, to create a code "Frankenstein" - mixing composition with aggregation - and the compiler would not stop you, but that doesn’t mean that this would be a good and valid design.

0

Trying to be very succinct:

In aggregation, an object A is referenced, or "called" within another object B. That is, you create two objects A and B and an attribute of B is object A (one is part of the other). But for that to happen, the two must exist, independent of each other. By this independence (coexistence), they say that "the part can live without the whole". What does that mean? I said that 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.

In 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 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 a method adopt(pet), in which he adopts a cat. The function creates an attribute for Owner who receives a cat. If I put as owner argument.adopt(pet) the cat object that was created, Dono now has the cat as one of its attributes. And this is exactly the same cat that was created. But if owner ceases to exist, the cat continues to exist normally, because it already existed before.

Composition Example: Now say I create the Person class and the Address class. I create the Person object. Do you agree with me that it makes little sense for me to 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 his and only hers (except whoever lived with him). Then it would make more sense for me to create an address attribute within the Person class, which will receive parameters relating to specific address information of each person object that is created. If the person object is deleted, it makes no sense to have an address object. And as it was defined within person, it will be deleted in the same way.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.