Composite
Intent
To "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
Problem
When defining Part objects and Whole objects that act as containers for Part objects, clients must treat them separately, which complicates client code.
Solution
Define a unified Component interface for both part (Leaf) objects and whole (Composite) objects.
Individual Leaf objects implement the Component interface directly, and Composite objects forward requests to their child components.
Advantages
✅ Simplifies client code. ✅ Adding new component is easy. ✅ Allows building and changing complex hierarchies dynamically at run-time.
Disadvantages
❌ Uniformity versus type safety.
When to Use
Composite should be used when clients ignore the difference between compositions of objects and individual objects. If programmers find that they are using multiple objects in the same way, and often have nearly identical code to handle each of them, then composite is a good choice; it is less complex in this situation to treat primitives and composites as homogeneous.
Notes
The Composite design pattern emphasizes uniformity over type safety.
Design for uniformity
Child-related operations are defined in the Component interface. This enables clients to treat Leaf and Composite objects uniformly. But type safety is lost because clients can perform child-related operations on Leaf objects.
Design for type safety
Child-related operations are defined only in the Composite class. Clients must treat Leaf and Composite objects differently. But type safety is gained because clients cannot perform child-related operations on Leaf objects.
Last updated