Home computickets Aggregation and composition

Aggregation and composition

Author

Date

Category

Hello!

I always thought that aggregation is synonymous with composition, but I came across a blog on the Internet where shows the differences between composition and aggregation .

It blew me away. Please explain the pros / cons of both with small examples. How does this affect extensibility, testability, etc.


Answer 1, authority 100%

There are several types of interaction between objects, united under the general concept of “Has-A Relationship” or “Part Of Relationship”. This relationship means that one object is an integral part of another object.

There are two subspecies of this relationship: if one object creates another object and the lifetime of the “part” depends on the lifetime of the whole, then this is called “composition”, if one object receives a reference (pointer) to another object during construction, then this is already an aggregation.

Let’s take a look at an example from the .NET Framework to see the limitations / implications of this relationship: StringWriter + StringBuilder .

The StringWriter class is a specialized version of the TextWriter class, which is used extensively in serialization and to get the textual representation of objects.

Specifically, StringWriter creates a string representation of an object or graph of objects and relies on an instance of StringBuilder to work. Those. we can say that ‘StringWriter HAS A StringBuilder’ or ‘StringBuilder is part of StringWriter’. Now let’s see how to decide whether StringWriter should receive an instance of StringBuilder from the outside or create one?

On the one hand, as a client of the StringWriter class, we often do not care what exactly is used inside this class to obtain a string representation. This means that for ease of use, it is best for StringWriter to instantiate StringBuilder on its own.

But, on the other hand, a specific StringWriter object can only be responsible for getting part of the string representation, and the other part of the string can be calculated in a different way. From this point of view, it is best for StringWriter to take an instance of StringBuilder in the constructor. The same is true for high-load systems, in which it is reasonable to use an object pool.

Since StringWriter is a library class that must support both scripts, it has overloaded versions of the constructor: one of them creates a StringBuilder inside, and the other accepts it outside.

In other words, choosing between composition and aggregation is based on balancing different design requirements:

Composition: Object A controls the lifetime of Object B

Pros:

  • Composition allows you to hide the object usage relationship from the client’s eyes.

  • Makes the API for using a class simpler and allows you to move from using one class to another (for example, StringWriter could change the implementation and start using a different type, for example CustomStringBuilder ).

Cons:

  • The relationship is rather rigid, since one object must be able to create another: it must know a specific type and have access to the creation function. Composition does not allow interfaces (without involving factories) and requires the class to have access to the constructor of another class: Imagine the constructor StringBuilder is internal, or it is the interface IStringBuilder and only the client code knows which instance should be used here and now.

Aggregation: Object A gets a link to Object B

Pros:

  • Loose coupling between an object and its client. Now we can use interfaces and one object does not need to know how to create another object.

  • Great flexibility. Follows from the first paragraph

Cons:

  • Exposing implementation details. Since the client of the class must provide a dependency at the time of object creation (pass an instance of StringBuilder at the time of creation of StringWriter , the very fact of this relationship becomes known to the client.

  • The first point implies an increase in the complexity of the work of clients, as well as a greater “toughness” of the decision in the long term. Now the author of the TextWriter class can no longer make a decision on his own and move from StringBuilder to something else. Yes, you can “add another layer of abstraction” and highlight the IStringBuilder interface, but breaking this relationship will not be possible without breaking all existing clients.

In conclusion: design is about finding a compromise between various factors. Composition is simpler from the point of view of the clients of the class, but it imposes certain restrictions: the “whole” must be able to create a “constituent part”. Aggregation is more flexible, but it imposes other restrictions: now the “whole” does not hide the existence of a “component”, and therefore cannot replace it with another “component” in the future.

P.S. If you really want to use an example from the real world, then a screwdriver may be suitable to explain composition and aggregation. If the screwdriver is solid, i.e. the handle and the nozzle are tightly connected to each other, then we have a composition relationship. If the nozzle is removable and can exist without a handle or be used with another handle, then we have a aggregation relationship.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions