The Composite pattern allows you to treat individual objects and groups of objects in the same way. It’s useful for building tree-like structures—such as folders, menus, or graphical elements—where each part, whether simple or complex, supports the same operations.
Many applications deal with structures that mix simple and complex elements. Without this pattern, you’d need different logic to handle each type, leading to repetitive and error-prone code. The Composite pattern unifies them under one interface, so they can be processed in the same way.
Use the Composite pattern when:
Avoid this pattern if:
The Composite pattern defines three main components:
Both Leaf
and Composite
follow the same interface, making them interchangeable in the structure.
Think of a company org chart. An employee is a leaf. A department manager (composite) oversees a group of employees and possibly other departments. Whether you’re asking for a report from a person or a department, you use the same method.
Here’s a basic implementation in Python:
from typing import List
class Component:
def operation(self) -> str:
pass
class Leaf(Component):
def __init__(self, name: str):
self.name = name
def operation(self) -> str:
return f"Leaf({self.name})"
class Composite(Component):
def __init__(self, name: str):
self.name = name
self._children: List[Component] = []
def add(self, component: Component) -> None:
self._children.append(component)
def remove(self, component: Component) -> None:
self._children.remove(component)
def operation(self) -> str:
results = [child.operation() for child in self._children]
return f"Composite({self.name})[{' + '.join(results)}]"
root = Composite("root")
leaf1 = Leaf("A")
leaf2 = Leaf("B")
subtree = Composite("branch")
subtree.add(Leaf("C"))
root.add(leaf1)
root.add(subtree)
root.add(leaf2)
print(root.operation()) # Output: Composite(root)[Leaf(A) + Composite(branch)[Leaf(C)] + Leaf(B)]
See the full implementation here: Composite Pattern on GitHub