The Composite pattern is implemented by defining a common component interface for both individual objects (leaves) and groups of objects (composites), where composite classes hold a collection of child components and delegate operations to them recursively.
Key Points: • Define a Component interface with the operations shared by leaves and composites, such as operation(). • Leaf classes implement Component directly with no children. • Composite classes implement Component and additionally hold a List<Component>, with add()/remove() methods to manage children. • The composite's operation() method loops over its children and calls operation() on each, achieving recursion. • Client code interacts only through the Component interface, never checking whether it holds a leaf or composite.
Example: A menu system where MenuItem is a leaf and Menu is a composite holding a list of MenuItem/Menu children lets print() work identically on a single item or a whole nested menu.
Code Example:
interface Component {
void operation();
}
class Leaf implements Component {
public void operation() { System.out.println("Leaf operation"); }
}
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component c) { children.add(c); }
public void remove(Component c) { children.remove(c); }
public void operation() {
for (Component child : children) {
child.operation();
}
}
}Interview Tip: A concise interview answer is:
"I define a Component interface shared by leaves and composites, make Leaf implement it directly, and make Composite hold a list of children and implement the same method by delegating to each child recursively. That way the client always calls the same interface method whether it's operating on a single leaf or an entire subtree."