Composite is powerful when part-whole hierarchies should be handled through one uniform interface.
Compose objects into tree structures so clients can treat individual objects and compositions uniformly.
What the pattern is trying to do
Compose objects into tree structures so clients can treat individual objects and compositions uniformly.
What force creates the need
The domain has nested part-whole structures, but client code becomes messy if it must constantly distinguish leaf nodes from groups.
How the pattern responds
Represent leaves and composites behind one shared contract so operations can apply recursively with uniform client logic.
How the moving parts fit together
A component interface is implemented by both leaf objects and composite containers, allowing recursive traversal and uniform invocation.
Java example in the Order Management domain
package org.javaomnibus.ecommerce.gof.structural;
public interface LineItemNode {
Money total();
}
public final class ProductLineItem implements LineItemNode {
private final Money price;
public ProductLineItem(Money price) {
this.price = price;
}
@Override
public Money total() {
return price;
}
}
public final class BundleLineItem implements LineItemNode {
private final java.util.List children;
public BundleLineItem(java.util.List children) {
this.children = children;
}
@Override
public Money total() {
Money sum = Money.zero();
for (LineItemNode child : children) {
sum = sum.add(child.total());
}
return sum;
}
}
Step by step
- Both a single product line item and a bundle expose the same total operation.
- Clients do not need special-case logic for leaves versus composites.
- The recursive design fits naturally when the domain is truly hierarchical.
- Composite earns its place when uniform treatment matters more than strict type distinction.
Where this pattern helps
- When the domain includes trees, bundles, menus, org charts, or nested rule structures
- When recursive operations should apply uniformly to single items and grouped items
When a simpler design is better
- When the domain is not really hierarchical
- When leaf and composite behaviors are so different that a shared contract becomes misleading
What this pattern costs
- Can blur the distinction between valid operations on leaves and containers
- Recursive structures demand careful thinking about traversal, mutation, and invariants
How this fits today
Composite remains useful in Java for catalog trees, workflow graphs, document structures, rule sets, and any domain where nested structures are first-class.
Where teams get it wrong
Forcing a composite shape onto a flat domain often creates unnatural APIs and hides important distinctions between simple and grouped entities.