Composite pattern
Learn how the composite pattern lets you treat individual objects and groups uniformly, building tree structures where clients never distinguish leaves from branches.
Introduction
Composite is a structural pattern for part-whole hierarchies. A leaf represents one item; a composite represents a group of components and delegates the same operation to its children.
TL;DR / mental model
Model the tree behind one component interface. A leaf answers for itself; a composite asks each child and combines the results. The client calls one operation on either kind of node without writing type checks or recursion.
The Problem It Solves
A file system has files and directories. A directory can contain files or other directories. You need to calculate total size, print the tree, or search for a file, and the logic should work the same whether you are looking at a single file or an entire folder hierarchy.
Without the pattern, every operation turns into an instanceof chain:
This is brittle. Every new node type forces you to reopen every method that touches the tree. The Composite pattern eliminates this by giving leaves and containers a shared interface. Here is what changes when you apply it.
Structure
FileSystemNode is the component interface that both leaves and composites implement. File is the leaf: it has no children and returns its own size directly. Directory is the composite: it holds a list of FileSystemNode children and delegates getSize() to each of them. The client calls getSize() on any node without knowing what is underneath.
Participants
- Component: the shared interface for operations that make sense on both individual items and groups.
- Leaf: represents one item and handles the operation directly because it has no children.
- Composite: stores child components and combines or delegates the operation recursively.
- Client: works through the component interface and does not need to distinguish leaves from composites.
Implementation
Composite is useful when a tree structure makes callers write repeated instanceof checks to distinguish nodes. The key insight is to push the recursion into the tree itself so the client does not have to write it.
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with SDEpedia Premium.
Related Articles
Learn how the bridge pattern separates abstraction from implementation so both hierarchies grow independently, preventing class explosion when two axes of variation exist.
The iterator pattern provides a uniform way to traverse any collection without exposing its internal structure. Decouple traversal logic from the data it walks over.
The decorator pattern wraps objects to add behavior at runtime without modifying the original class. Stack decorators like layers, each adding one responsibility while keeping the same interface.