Composite Design Pattern
Pattern: Composite is a structural design pattern that lets you compose objects into tree structures to represent whole-part hierarchies.
Suppose we have created a simple shape drawing application that can draw basic geometric shapes. Suppose, further, the following is a partial class diagram for this system.
Problem: We want our drawing editor to support grouping and ungrouping operations so that several shapes can be collected together and treated as a single entity.
Solution 1: We could add a group member field into AbstractShape
to indicate which group each shape belongs to (using the number -1 to indicate that the object is not in any group).
- Pros: simple
- Cons: cannot support nested groups
Solution 2: Introduce a new class ShapeGroup
to manage a group of shapes.
- Pros: Supports nested groups
- Cons: You would have to treat primitives (
shapes
) and container classes (shapeGroups
) differently, making the application more complex than necessary.
Solution 3: Implement the ShapeGroup
class as a subclass of Shape
.
The ShapeGroup
class provides a means by which several shapes can be grouped into a single entity that behaves in the same way as a single shape.
The composite design pattern provides a means of grouping together several objects of type
T
such that the grouped object is also of typeT
.
In the diagram above
Component
:- Declares the abstraction for objects in the composition.
- Could optionally implement default behavior common to all subclasses.
Composite
:- Represents an aggregate object (collection of components).
- Usually has methods to add/remove components.
- Typically implements operations of
Component
simply by calling the same operation for each of its constituent components.
ConcreteComponent
(a.k.a Leaf)- Defines behavior for primitive objects in the composition.
When to use this pattern?
- Need to manipulate a hierarchical collection of "primitive" and "aggregate" objects.
- Need to process (treat) primitive objects the same way as aggregate objects.
- Examples: file/folder hierarchies, organizational charts, tables of contents, parsing structured documents like XML/HTML, etc.
Advantage: Clients typically only need to interact with the Component
interface; they would be unaware if they're dealing with a composite or a leaf object. This hides the complexity of the data structure from the outside world.