Composite Pattern
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
Composite = file folders. A folder can contain files AND other folders. 'Get size' works the same whether you call it on a single file or a folder-of-folders — it just recurses down the tree.
The pattern defines a Component interface implemented by both Leaf (no children) and Composite (has children). Clients call operations on a Component reference — whether it's a leaf or a composite is transparent. Examples: file system (File and Directory both implement FileSystemNode with size() — directory.size() recursively sums children); UI widget tree (Button and Panel both implement Widget with render()); expression trees (Literal and BinaryExpression both implement Expression with evaluate()).
The classic Composite challenge is the 'safe vs transparent' trade-off: should add()/remove()/getChildren() be on the Component interface (transparent — callers can call on a Leaf, which must throw; or no-op) or only on Composite (safe — callers need to cast to Composite to manage children)? The GoF recommends transparency for ease of use; in practice, safety (type-check explicitly) is more common. Composite is also naturally recursive — any composite operation that visits the tree must handle cycles if the structure is a graph rather than a true tree. This is common in file system symlinks or UI component references.
Composite is the pattern when I need to treat a tree uniformly. In a permissions system: Permission is the component interface with isAllowed(action). SinglePermission is a leaf; PermissionGroup is a composite that checks all children. The service calls permission.isAllowed() without knowing whether it's a single permission or a group of groups. This is also the pattern for menu systems, expression parsers, and organizational hierarchies. The design decision I always flag: where to put add/remove — on the component interface for transparency, or only on the composite class for type safety.
Composite assumes a tree structure. If the structure has cycles (directed graph), recursive operations must track visited nodes or they will loop infinitely.