Composite Pattern

What is the Composite pattern?

Composite means: build a tree of objects — folders containing files, bundles containing products — and let a single leaf and a whole group answer the same calls through one shared interface.

A file and a folder both answer “what is your size?” A product and a gift set both answer “what is your price?” The caller never needs a special case for “is this a group?”

Two roles show up:

  • Leaf — an individual thing with no children (a file, a single item).
  • Composite — a thing that contains children, which may themselves be leaves or composites (a directory, a bundle).

Both implement the same component interface. A composite forwards operations to its children and combines the results.


The problem it solves

Without Composite, totaling a group of things often turns into type checks:

Every new operation — print a label, apply a discount, export to JSON — risks another nest of type checks. Composite moves the branching into the objects themselves: leaves answer directly, groups ask their children.


A file-system example

The caller never asks “are you a file or a directory?” It just calls display and getSize.


A shop bundle example

The same shape works for products.

Bundles can nest inside bundles. The total still works, no matter how deep.


When it helps

Use Composite when your domain is naturally a tree and the same operations make sense on both leaves and groups: size, price, draw, validate, export.

It shines when client code would otherwise fill up with “if leaf / if group” branches for every new feature.


When it hurts

If the structure is flat — just a list of independent items — Composite adds ceremony without benefit.

Be careful with operations that only make sense for groups, like add(child). If you put add on the shared interface, leaves must either throw or no-op, which can surprise callers. Many designs keep child management on the composite type only. Also watch performance on huge trees: a naive recursive size walk touches everything every time.


Practical tips

  • Define a small component interface with operations meaningful for both leaves and groups.
  • Keep leaf classes simple; put child lists only on composites.
  • Prefer recursion that is easy to read over clever micro-optimizations, until profiling says otherwise.
  • Document whether the order of children matters.
  • Do not force Composite onto problems that are really just plain collections.

Check your understanding

What is Composite, in one sentence?
A design that lets individual objects and groups of objects share one interface in a tree.

What is a leaf?
A node with no children.

What is a composite?
A node that contains children and usually forwards operations to them.

Why do callers like it?
They can ignore the difference between one item and a nested group.


What to learn next

Next: Strategy Pattern — the focus shifts from how objects are arranged to how behavior is chosen and swapped.