askvity

What is the Pattern of Composition?

Published in Design Pattern 4 mins read

The pattern of composition, often referred to as the Composite pattern, describes how to structure objects so that individual objects and groups of objects are treated uniformly.

The Composite pattern is a structural design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. As described in the reference, it "describes a group of objects that are treated the same way as a single instance of the same type of object". The primary intent is to "compose" these objects into tree structures.

Understanding the Composite Pattern

At its core, the Composite pattern enables clients to treat individual objects and compositions of objects uniformly. This means you can write code that operates on a single object or a collection of objects without needing to know the specific type.

Key Concepts

  • Part-Whole Hierarchies: The pattern is ideal for representing structures where a complex object is composed of smaller, simpler objects, and these smaller objects can themselves be composed of even smaller ones, forming a hierarchical structure. Think of an organization chart, a file system, or graphical shapes grouped together.
  • Uniformity: The key benefit is the ability to interact with both individual "leaf" objects and "composite" objects (which contain other objects) through a common interface.
  • Tree Structures: The pattern naturally leads to tree-like data structures where composite nodes can have children, and leaf nodes are endpoints.

Core Components

The Composite pattern typically involves three main roles:

Component Name Description Example (File System)
Component This is the abstract base class or interface for all objects in the composition. It declares the interface for both leaf and composite objects, including methods for accessing and managing child components (optional, but often included for composite objects). FileSystemEntry
Leaf Represents individual objects that have no children within the composition. These are the "parts" at the lowest level of the hierarchy. File
Composite Represents objects that can contain other components (both Leaf and Composite objects). It implements the Component interface and often includes methods to add, remove, and get children. Directory

How it Works

The Composite class maintains a collection of Component objects. Both Leaf and Composite objects inherit from or implement the Component interface. When a client interacts with a Component, the behavior depends on whether it's a Leaf (it performs the action directly) or a Composite (it typically delegates the action to its children).

Example: File System

Consider a file system:

  • FileSystemEntry could be the Component interface with methods like getName(), getSize(), display(indentation).
  • File is a Leaf. Its getSize() returns the file size; display() prints the file name with indentation.
  • Directory is a Composite. Its getSize() calculates the total size of all contained files and subdirectories; display() prints its own name and then calls display() on all its children, increasing the indentation.

A client can call getSize() or display() on a File object or a Directory object, and the appropriate behavior occurs automatically, demonstrating uniform treatment.

Benefits and Use Cases

  • Simplified Client Code: Clients don't need to differentiate between single objects and compositions.
  • Easier Extension: Adding new types of Components is simpler as long as they adhere to the Component interface.
  • Flexible Structure: Allows for complex tree structures to be built and manipulated easily.

This pattern is widely used in GUI toolkits (where panels contain widgets, which can be other panels), document structures (like XML or HTML DOM), and scenarios requiring tree-like representations of hierarchical data.

Related Articles