Aggregation & Composition
Amit Nadiger
Polyglot(Rust??, Move, C++, C, Kotlin, Java) Blockchain, Polkadot, UTXO, Substrate, Sui, Aptos, Wasm, Proxy-wasm,AndroidTV, Dvb, STB, Linux, Cas, Engineering management.
Object-oriented programming allows for complex software systems to be created using a modular and scalable approach. Two important concepts in OOP are Aggregation and Composition, which describe different types of relationships between classes and objects. In this article, we will explore the mainly the differences between Aggregation and Composition and provide suitable examples of when to use each.
Code reuse is an important goal of object-oriented programming. The advantage of code reuse is that it allows developers to write less code and increase the efficiency of the program. This can save time and reduce the potential for errors, as the reused code has already been tested and debugged. Additionally, code reuse can lead to better maintainability, as changes made to the reused code will automatically be reflected in all parts of the program that use that code. This goal is achieved by inheritance, aggregation, and composition.
Inheritance allows a subclass to reuse code from its superclass. By inheriting properties and behavior from the superclass, the subclass can avoid duplicating code and reduce the amount of code that needs to be written. This can make the code more efficient and easier to maintain, as changes made to the superclass will automatically be inherited by the subclass.
Aggregation and composition also allow for code reuse through delegation. In both cases, a new class is created that contains an instance of an existing class. The new class can then delegate some of its responsibilities to the existing class, allowing it to reuse code and avoid duplicating functionality. The difference between aggregation and composition is the degree of ownership of the existing class: with aggregation, the existing class can still exist independently of the new class, while with composition, the existing class is owned exclusively by the new class and cannot exist independently.
However, it is important to remember that code reuse should not be the only consideration when designing a program. Other factors, such as flexibility, modularity, and scalability, should also be taken into account. In some cases, inheritance, aggregation, or composition may not be the best approach for achieving these goals, and other design patterns or techniques may need to be used.
The most common mistake that less experienced developers make is to overuse inheritance and overlook the benefits of delegation. This can lead to code that is tightly coupled and difficult to maintain or extend. Instead, developers should carefully consider their design and choose the appropriate approach for their specific needs. In many cases, delegation through aggregation or composition can be a more flexible and modular approach to code reuse than inheritance.
Inheritance is a mechanism in object-oriented programming where one class inherits properties and behavior from another class i.e., "is-a" relationship. This can be useful for code reuse, as a subclass can reuse the code of its superclass and add new functionality as needed. However, inheritance can also lead to tight coupling between classes, as changes to the superclass can have unintended consequences for the subclass. This can make the code difficult to maintain, modify, or extend.
Delegation, on the other hand, involves creating a new class that contains an instance of the existing class and delegates some of its responsibilities to it. This allows for greater flexibility and modularity in the design, as well as better control over the interactions between classes. Aggregation and composition are two ways to achieve delegation.
Aggregation is a relationship between two classes where one class is a "has-a" relationship to the other class. This means that the first class contains an instance of the second class, but the second class can still exist independently of the first class. For example, a car has an engine, but the engine can exist independently of the car.
Composition, on the other hand, is a stronger form of aggregation where the second class is owned by the first class. This means that the second class cannot exist independently of the first class. In other words, the two classes have a "part-of" relationship, where the first class "has" an instance of the second class and controls its lifetime.For example, a house is composed of many rooms, but each room is exclusively part of one house.
let me try to elaborate more on aggregation and composition.
Aggregation
Aggregation is a type of relationship between classes in which one class has a reference to another class, but the second class can exist independently of the first. The two classes have a "has-a" relationship, where the first class "has" an instance of the second class, but does not control its lifetime. The second class can be shared among multiple instances of the first class.
? ? ? ? ? ? ? ? ? +-------------+
? ? ? ? ? ? ? ? ? |? ?ClassA? ? |
? ? ? ? ? ? ? ? ? +-------------+
? ? ? ? ? ? ? ? ? | -part1: Part|
? ? ? ? ? ? ? ? ? | -part2: Part|
? ? ? ? ? ? ? ? ? +-------------+
? ? ? ? ? ? ? ? ? ? ? ? ? ?^
? ? ? ? ? ? ? ? ? ? ? ? ? ?|
? ? ? ? ? ? ? ? ? +-------------+
? ? ? ? ? ? ? ? ? |? ? Part? ? ?|
? ? ? ? ? ? ? ? ? +-------------+
? ? ? ? ? ? ? ? ? |? ? ? ? ? ? ?|
? ? ? ? ? ? ? ? ? +-------------+
In the above diagram, ClassA has an aggregation relationship with Part. This means that ClassA uses Part objects, but does not own them. The parts can exist outside of the ClassA object and can be used by other objects. This is represented by the empty diamond at the end of the association line between ClassA and Part.
Aggregation is often implemented using pointers or references. In C++, the first class holds a pointer or reference to the second class, but the second class is dynamically allocated and can exist independently of the first class. Here's an example:
class Author {
// implementation details
};
class Book {
private:
vector<Author*> authors;
public:
void addAuthor(Author* author) {
authors.push_back(author);
}
// other methods
};
In the above example, the Book class has a vector of Author pointers. Each Book can have many Authors, but each Author can also write many Books. The Author class can exist independently of the Book class, and can be shared among multiple Book objects.
Advantages of Aggregation:
Disadvantages of Aggregation:
领英推荐
Suitable Scenarios for Aggregation:
Composition
Composition is a type of relationship between classes in which one class owns another class, and the second class cannot exist independently of the first. The two classes have a "part-of" relationship, where the first class "has" an instance of the second class and controls its lifetime. The second class is exclusively owned by the first class, and cannot be shared among multiple instances of the first class.
Composition is often implemented using object instances. In C++, the first class owns an instance of the second class, which is statically allocated and part of the first class. Here's an example:
class Room {
// implementation details
};
class House {
private:
vector<Room> rooms;
public:
void addRoom(const Room& room) {
rooms.push_back(room);
}
// other methods
};
In this example, the House class has a vector of Room objects. A House is made up of many Rooms, but each Room is exclusively part of one House. The Room objects are statically allocated and part of the House class.
Advantages of Composition:
Disadvantages of Composition:
1.Rigidity: Composition provides less flexibility in the design of the system, as the second class is exclusively owned by the first class.
Suitable Scenarios for Composition:
Differences between Aggregation and Composition:
In aggregation, the first class holds a pointer or reference to the second class, whereas in composition, the first class owns an instance of the second class.
In the aggregation example I provided earlier, the Book class holds a vector of Author pointers using the following code:
vector<Author*> authors;
Here, each element in the vector is a pointer to an Author object, which is dynamically allocated and can exist independently of the Book class.
In contrast, in the composition example I provided earlier, the House class owns a vector of Room objects using the following code:
vector<Room> rooms;
Here, each element in the vector is an instance of the Room class, which is part of the House class and cannot exist independently.
In conclusion, both Aggregation and Composition are important concepts in object-oriented programming. While Aggregation provides flexibility and code reusability, Composition provides a stronger relationship between classes and easier memory management. Understanding the differences between the two can help developers choose the appropriate approach for their specific needs.
Thanks for reading till end, please comment if you any.
Lead Software Engineer, Resource Manager, Writer, Mentor, Crazy Runner from Brave Ukraine | EPAM Systems
7 个月Useful reading, thanks!