Structural Object Tree

Composite

Composite is a structural pattern that lets individual objects and groups of objects be treated through the same interface, so client code can operate on a whole tree without caring how deep it goes.

Complexity
Popularity

Problem

A file manager needs to compute the total size of anything a user selects: a single file, or a directory that itself contains files and other directories nested several levels deep. The obvious first attempt writes a function that checks `if (item.type === 'file')` versus `if (item.type === 'directory')` and sums up children in the directory branch.

That branch multiplies everywhere size is computed - disk-usage reports, copy previews, quota checks - and every one of them has to be kept in sync. Add a third kind of filesystem entry, like a symlink that points at a directory, and every one of those call sites needs a new branch.

Solution

Give every filesystem entry - files and directories alike - the same interface, say a `getSize()` method. A file simply returns its own size. A directory implements `getSize()` by looping over whatever it contains and summing each child's `getSize()`, regardless of whether that child is itself a file or another directory.

Because a directory calls the exact same method it exposes, the recursion handles arbitrary nesting for free. Any code that needs a size just calls `getSize()` on whatever it was handed, without ever branching on what kind of item it is.

When to Use

  • Your domain is naturally a part-whole hierarchy - folders and files, menus and menu items, org charts, nested UI layouts.
  • You want callers to run the same operation on a single item or an entire subtree without writing separate code paths for each case.

Real-World Examples

  • **Filesystem APIs** - a `File` and a `Directory` both expose size and traversal operations; computing a folder's total size just recurses through whatever it contains.
  • **DOM tree** - a text node and an element node both implement the same `Node` interface, so traversal code like `querySelectorAll` works uniformly at any depth.
  • **Protobuf / JSON AST parsers** - a scalar value and a nested object both conform to one node interface, letting a single visitor function walk the entire parsed tree.