Composite Pattern

Build tree structures where a single item and a group of items share one interface, so callers run the same operation on either without checking which they hold.

Overview

The problem it solves Some data is a tree: folders hold files and folders, a UI panel holds buttons and panels, an expression holds numbers and sub-expressions. Code that walks such a tree tends to fill up with checks: is this a leaf or a group? The Composite pattern gives leaves and groups one interface. A group implements each operation by asking its children, and the recursion takes care of the rest.

The pattern is a structural pattern from the Gang of Four book (Gamma, Helm, Johnson and Vlissides, *Design Patterns*, 1994). Its roles are Component (the shared interface), Leaf (an item with no children) and Composite (a node that holds children of type Component).

How a recursive operation runs Asking a directory for its size asks each child. Files answer at once; directories ask their own children first. The recursion ends at the leaves, and no caller ever writes the loop.

  • notes.txt — Leaf — Returns 15
  • old/ — Composite — Sums its one child: 15
  • guide.md — Leaf — Returns 20
  • docs/ — Composite — 20 + 15 = 35
  • root — Composite — 35 + 10 + 15 = 60

A runnable example The file system version, including a search that also works on any node.

A second tree: expressions The same shape evaluates arithmetic. Numbers are leaves; operators are composites with exactly two children. Building the tree is the parsing step; evaluating it is one method.

Transparency or safety The one design decision the pattern forces: where do add and remove live?

  • Transparency — On Component, so leaves have them too — Callers treat every node the same — A leaf must refuse or ignore add; the error shows at run time
  • Safety — On Composite only — The compiler stops file.add(...) — Callers must check the type before adding

Both choices are defensible, and interviewers expect you to name the trade. Transparency keeps every node uniform, which matters most in dynamic languages. Most modern typed code, including the example above, chooses safety: add is only on Directory, and the few places that build trees know they are holding a directory. The operations that callers run on any node (size, find) stay on the interface, which is where uniformity matters.

What you will be able to do - Name Component, Leaf and Composite and say which one holds the recursion. - Write a tree where an operation on the root works with one method and no type checks. - Explain the transparency-versus-safety choice and defend one of them. - Reuse the shape for file systems, UI trees, expression trees and org charts. - Say how Iterator and Visitor combine with a composite.

Interview questions

  • What are the roles in the Composite pattern, and what does each one own?
  • Show the smell that Composite removes, and the fix.
  • Where should add and remove go: on the Component or only on the Composite?
  • How do you stop a composite from containing itself, and do children need a parent link?
  • How do Iterator and Visitor fit with a composite?

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio