Composition vs. Aggregation
Master the 'Has-A' relationship. Learn the difference between weak references and strong ownership to design robust object hierarchies.
In the last post, we looked at how to draw a class box. But the real magic of LLD isn't in the boxes - it's in the lines between them. Specifically, how objects own or reference each other.
I used to get confused between "has-a" relationships. Is a Car "having" an Engine the same as a Library "having" a Book? In code, both might look like a simple field, but in design, they are completely different.
The "Has-A" Spectrum
Both Aggregation and Composition are types of Association where one object contains another. We call this a Has-A relationship.
- Aggregation: Weak ownership. The child can exist without the parent.
- Composition: Strong ownership. The child dies with the parent.
1. Aggregation (The Weak Link)
Aggregation is a relationship where the "part" can exist independently of the "whole."
- Analogy: A Library and its Books. If the library building is demolished, the books don't magically vanish. They can be moved to another library or a student's shelf.
- Code Clue: The child object is usually passed into the parent's constructor or a setter. The parent doesn't "create" it; it just "uses" it.
- UML Notation: A line with a hollow diamond at the parent end.
2. Composition (The Death Bond)
Composition is a much stronger relationship. Here, the "part" is physically or logically inseparable from the "whole." The child's lifecycle is managed entirely by the parent.
- Analogy: A Car and its Engine. While you could technically swap an engine, in the context of a specific car's design, the engine is a part of that car. If the car is sent to the scrapyard and crushed, that specific engine instance is destroyed with it.
- Even better analogy: A Human and their Heart. You can't have a functioning human heart sitting on a table without a human (for long). They live and die together.
- Code Clue: The parent class usually creates the child instance inside its own constructor (
this.engine = new Engine()). - UML Notation: A line with a solid diamond at the parent end.
Aggregation vs. Composition: The Decision Matrix
When you're in an interview and trying to decide which diamond to draw, ask yourself this one question: "If I delete the parent, should the child be deleted too?"
| Feature | Aggregation | Composition |
|---|---|---|
| Relationship | Weak "Has-A" | Strong "Has-A" |
| Ownership | Shared / Independent | Exclusive Ownership |
| Lifecycle | Child outlives Parent | Child dies with Parent |
| UML Symbol | Hollow Diamond | Solid Diamond |
| Real-World Ex | Department has Professors | House has Rooms |
Why This Matters for LLD
Choosing the wrong one leads to major bugs:
- Over-using Composition: You make your system rigid. If everything dies with its parent, you can't reuse objects or move them around.
- Over-using Aggregation: You risk "memory leaks" or orphaned objects. You might delete a "User" but leave their "Profile Settings" hanging around in the database because you didn't define a strong ownership.
[!IMPORTANT] Don't confuse this with IS-A Remember, Inheritance is an IS-A relationship (A Dog is an Animal). Aggregation and Composition are HAS-A relationships (A Car has a Wheel).
Further Reading and Watching
- Watch: UML Diagrams Full Course by freeCodeCamp: The definitive guide that covers structural relationships in extreme detail.
- Read: Aggregation vs Composition by Baeldung: A great code-centric view of these concepts.
Now that you can model how objects own each other, it's time to see how they live on the actual hardware. In the next part, we'll look at Component and Deployment Diagrams.
Keep reading