Structural 5 — Composite
In one line
Treat individual objects and groups of objects uniformly — a tree where leaves and nodes share an interface.
Think of it like this
A folder on your computer. A folder can hold files AND other folders, and 'get size' works the same on both: a file returns its size, a folder adds up everything inside it.
Key ideas
- 01
Solves: recursive structures — org chart, file system, UI component tree, menu.
- 02
Component interface → Leaf and Composite both implement it; composite holds children.
- 03
price() or size() recurses: a folder's size is the sum of its children.
Java / Spring map
- →
java.awt.Component/Container; Spring's CompositePropertySource.
Code & diagrams
Pricing menu items or a folder of files — same method either way.
public interface MenuItem { double price(); }
public final class Dish implements MenuItem { // leaf
private final double price;
public Dish(double price) { this.price = price; }
public double price() { return price; }
}
public final class Combo implements MenuItem { // composite
private final List<MenuItem> items = new ArrayList<>();
public Combo add(MenuItem m) { items.add(m); return this; }
public double price() { // recursion
return items.stream().mapToDouble(MenuItem::price).sum();
}
}
// Meal deal = new Combo().add(new Dish(120)).add(new Dish(80)); → 200
// And a Combo can contain another Combo — unbounded nesting, one client.Explain without notes
Why does Composite give you the Open/Closed principle for free here?
Practice
Model a file/folder size tree with Composite.
Trade-offs
- ↔
Uniform interface can hide 'leaf-only' operations you end up guarding with instanceof.
Completion checklist
I can model any recursive part-whole structure with Composite and compute aggregates recursively.