Introduction
Many real‑world models are naturally hierarchical:
File systems: folders inside folders, containing files
UI components: windows containing panels, buttons, labels
Organization charts: departments containing teams, containing people
You often want to:
Operate on a single item (e.g., a file)
Or on a group of items (e.g., a folder with many files and subfolders)
Without writing separate logic for “single” vs “group” each time.
The Composite Design Pattern addresses this by making individual objects and groups implement the same interface, so client code can treat them uniformly.
Intent of the Composite pattern
The core intent:
Compose objects into tree structures and let clients treat individual objects and compositions of objects uniformly.Key ideas:
Define a common interface for both simple (leaf) and complex (composite) objects.
A leaf represents a single object (e.g., a file).
A composite contains children (leaf or composite) and implements operations by delegating to its children.
Client code uses the common interface and doesn’t care whether it’s dealing with a single item or an entire subtree.
In short: “Call operation() On one object or on a whole tree, the calling code looks the same.”
Basic structure: Component, Leaf, Composite
Typical roles:
Component
The base interface or abstract class.
Declares operations that both leaves and composites support.
Leaf
Represents end objects (no children).
Implements operations directly.
Composite
Holds a collection of
Component*Implements operations by iterating over its children and delegating calls.
C++ example: File system (folders and files)
Step 1: Component interface
The show function prints the node with indentation to reflect the tree structure.
Step 2: Leaf – File
Step 3: Composite – Folder
Step 4: Using the composite
Here:
Fileis a leaf.Folderis a composite.Both implement
FileSystemNode.Client code works with
FileSystemNode*and callsshow()On either a file or a folder (or the whole tree) in the same way.
Why is composite useful
Composite simplifies client code and makes hierarchies easy to work with:
Uniform treatment
Client code does not need
if (isFolder) ... else ....It just calls
node->show()node->operation()Regardless of whether it’s a leaf or composite.
Natural match for trees
Any structure that forms a tree (UI, menus, documents with sections) can be modeled cleanly.
Recursive operations
Operations naturally propagate down the tree: “print everything”, “calculate total size”, “apply permission changes to all children”, etc.
Flexible composition
You can nest composites inside composites (folders inside folders) without changing client code.
Composite often appears in frameworks and libraries that deal with nested structures, such as UI toolkits (containers containing widgets which can themselves be containers).
Another example: Graphic objects (shapes and groups)
Think of a drawing application:
Leaf: individual shapes like
Circle,Rectangle.Composite that can contain multiple shapes or groups.
Common interface:
Leaf:
Composite:
Usage:
Again, client code uses Graphic* and can draw a single shape or a whole group with one call.
When to use Composite (and when not to)
Use Composite when:
You have data that is naturally hierarchical or tree‑like.
You want the ability to treat a single object and a group of objects the same way.
Operations on the whole structure can be defined recursively (e.g., print, compute total, apply an action).
Be cautious or avoid Composite when:
The hierarchy is very simple and unlikely to grow; a plain container might be enough.
You don’t need uniform treatment; leaf and composite behavior are completely different and will always be handled separately.
The operations you need are very diverse and don’t fit well into one common interface.
As with other patterns, avoid overuse; apply Composite when it aligns with the problem’s structure.
Summary
The Composite Design Pattern is a structural pattern that:
Models part‑whole hierarchies as tree structures.
Let clients treat individual objects (leaves) and groups of objects (composites) uniformly through a common interface.
Naturally supports recursive operations over the whole structure.
You saw:
A C++ file system example (
FileandFolder) using aFileSystemNodeinterface.How a
Folderholds children and delegates operations likeshow()to them.A graphics example where
GraphicGroupManages multiple shapes.When Composite is a good fit in Low Level Design, especially for menus, file systems, UI trees, or organizational structures.