Explore Topics
Composite is a **structural** GoF pattern with one of the cleanest one-line intents in the catalog: "Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly." Read that twice. The first half is about **structure** (build a tree). The second half is about **uniformity** (the Client cannot tell ā and does not care ā whether the thing it is operating on is a single leaf or a 10,000-node forest). When `shape.draw("blue")` works identically on a `Triangle` and on a `Drawing` that contains 50 other Drawings, you have eliminated an entire class of `instanceof` checks from your client code.
- **Tree structure** ā leaves at the bottom, composites in the middle, each composite holds Components which themselves may be leaves or composites. The recursion is intentional and is the whole point.
- **Uniform treatment** ā the Client calls `component.operation()` without knowing or caring whether the component is a Leaf or a Composite. Polymorphism does the dispatch.
- **Recursion lives inside the Composite** ā the Client never writes a recursive loop. The Composite forwards each operation to its children, and the children either recurse further (if they are Composites themselves) or terminate (if they are Leaves).
- **One polymorphic call replaces N instanceof branches** ā every new node type would otherwise add another branch to every traversal site in the client code. With Composite, new node types just implement the Component interface.
- ā¦The Client becomes a one-liner. `drawing.draw("blue");` regardless of how deep the tree goes.
- ā¦Adding a new leaf or composite type is purely additive ā the existing Client code does not change at all (Open/Closed Principle).
- ā¦Recursive operations (sum, render, search, serialize, count) become natural ā the recursion is encoded once, in the Composite's implementation.
- ā³Defining a Component interface that fits **every** leaf and **every** composite is the hard part ā for some operations, "what should a Leaf return?" has no good answer.
- ā³It is easy to accidentally create a tree with cycles (composite A contains composite B contains composite A), and the recursive operations will then stack-overflow.
- ā³Operations that need to know "am I a leaf or a composite?" can pierce the abstraction and force `instanceof` checks back into the Client.