Composite Pattern
Compose objects into tree structures to represent part-whole hierarchies.
Intent & Objective
Let clients treat individual objects and compositions of objects uniformly using tree structures.
"An employee is an individual; a department is a group of employees. You can ask either an individual employee or a whole department to "report work." The department delegates to its members, but from your perspective, you interacted with one uniform entity."
"A song is an individual track; a playlist is a composite containing songs or nested playlists. You can press "play" on either, and it executes uniformly."
"A child is an individual; a parent is a composite containing children. If you ask "who is in the family?", both individuals and groups answer using the same interface."
"Treating individual sub-tasks, stories, and grouped epics uniformly in agile sprint tracking boards."
The Problem
Managing tree hierarchies (e.g., UI trees, file directories, compound graphic shapes) where client code needs endless `if (isFolder) { loop... } else { ... }` checks.
The Solution
Declare an interface that represents both simple and complex objects. Container objects hold a collection of children conforming to the same interface.
Key Participants & Architectural Roles
Code Samples (Traditional OOP vs Functional Programming)
Available in C++, Python, and JavaParadigm Contrast: Traditional OOP vs Functional / Data-Oriented
In OOP, Composite uses recursive class hierarchies. In Functional Programming, Composite is naturally modeled as an Algebraic Data Type (recursive sum types / rose trees) with pattern matching.
Advantages
- ✓ Treats complex tree structures uniformly via polymorphism
- ✓ Open/Closed Principle: easily add new element types into existing trees
Trade-offs
- ✗ Can make designs overly general when you want to restrict which components can be children of others
When to Apply
- → When you need to implement a tree-like object structure (GUI widgets, file systems, organizational hierarchies)
When to Avoid
- ! When your data is strictly flat with no nested or recursive parts