AlgoMaster Logo

Composition

Ashish

Ashish Pratap Singh

What if a relationship is so strong that the "part" is meaningless and cannot even exist without the "whole"?

This is the world of Composition.

Composition is the strongest form of association in object-oriented design. It models a “has-a” relationship between a whole and its parts—but unlike aggregation, composition comes with ownership and lifecycle dependency.

When you use composition, you're saying:

  • “This object is composed of other objects.”
  • “And if the container goes away, so do its parts.”

1. What is Composition?

Composition is a special type of association that signifies strong ownership between objects. The “whole” class is fully responsible for creating, managing, and destroying the “part” objects. In fact, the parts cannot exist without the whole.

Key Characteristics of Composition:

  • Represents a strong “has-a” relationship.
  • The whole owns the part and controls its lifecycle.
  • When the whole is destroyed, the parts are also destroyed.
  • The parts are not shared with any other object.
  • The part has no independent meaning or identity outside the whole.

If the part makes no sense without the whole, use composition.

2. UML Representation

In UML class diagrams, composition is represented by a filled diamond (◆) at the “whole” end of the relationship.

This diagram means:

  • A House owns one or more Room objects.
  • Rooms do not exist independently of the House.
  • If the House is deleted, all its Rooms are also deleted automatically.

In other words, the child class (Room) is tightly bound to the lifecycle of the parent class (House).

3. Code Example

Let’s model above example using code.

Room class

House class

Explanation

  • The House creates, manages, and owns its Room objects.
  • The Room objects do not exist independently outside the context of the House.
  • No external class should reuse or manage these Room instances.
  • If the House is deleted (e.g., garbage collected), the Rooms are destroyed too.

This demonstrates a true composition relationship—where object ownership and lifecycle are tightly coupled.

4. When to Use Composition

Use composition when:

  • The part is not meaningful without the whole.
  • The whole should control the lifecycle of its parts.
  • The parts are not reused elsewhere in the system.
  • You want to model a strong containment relationship.

Composition is a preferred alternative to inheritance when building flexible systems.

Favor composition over inheritance.” — GoF Design Principle

Why?

  • You can build complex behavior by composing smaller, reusable parts.
  • It avoids the tight coupling and fragility of inheritance hierarchies.
  • You can swap out parts dynamically to modify behavior.

For example:

  • A Vehicle can compose an Engine interface.
  • Swap between PetrolEngine, ElectricEngine, or HybridEngine at runtime.

This leads to cleaner, testable, and decoupled code.

5. Composition vs Aggregation vs Association

Let’s compare association, aggregation, and composition side-by-side to understand how they differ in ownership, lifecycle, reusability, and usage in real systems.

Feature
Association
Aggregation
Composition

Ownership

❌ None

❌ Weak — has-a

✅ Strong — owns-a

Lifecycle

❌ Independent

❌ Independent

✅ Dependent — part dies with whole

Tightness

Loose coupling

Moderate coupling

Tight coupling

Multiplicity

Flexible (1:1, 1:N, N:N)

Whole can group many parts

Whole composed of integral parts

Reusability

High — parts reusable

Moderate — parts often reused

Low — parts not reused outside

UML Symbol

Solid Line

Hollow Diamond (◊)

Filled Diamond (◆)

Real Example

Student ↔ Course

Department → Professor

House → Room

Think of it like this:

  • Association is a general connection: two classes simply know about each other.
  • Aggregation is a grouping: the whole and parts can exist independently.
  • Composition is an ownership: the part’s existence is bound to the whole.

So far, we’ve explored how objects in OOP can be connected in increasingly stronger ways, from simple associations, to looser aggregations, to tightly bound compositions.

But in many real-world designs, classes also rely on each other temporarily, not as part of their structure but during specific actions or method calls.

These short-lived, non-owning relationships are modeled through Dependency — the weakest form of connection in OOP.

Lets explore that in the next chapter.