1. Definition
The Composite Design Pattern lets clients treat individual objects and compositions of objects uniformly. In other words, it allows you to compose objects into tree structures to represent part-whole hierarchies.
2. Problem Statement
Suppose you have individual objects and also compositions of these objects. It becomes a challenge to treat them in the same way, especially when operations and behaviors need to be applied.
3. Solution
The Composite pattern suggests introducing a shared interface for both simple and complex objects. If we see a system as a tree structure, leaf nodes in the tree can represent simple objects while branches or nodes can represent complex objects (compositions).
4. Real-World Use Cases
1. Graphic systems where shapes can be made up of simpler shapes.
2. Organizational structures (e.g., a company's departments and employees).
3. File and directory systems.
5. Implementation Steps
1. Define a Component interface with methods that make sense for both simple and complex components.
2. Create Leaf classes that implement the Component interface.
3. Create Composite classes that also implement the Component interface, and can store child components.
4. Client code can treat both Leaf and Composite objects uniformly.
6. Implementation in Ruby
# Step 1: Component Interface
module GraphicComponent
def draw
raise NotImplementedError, 'Subclasses must define `draw`.'
end
def add(component)
end
def remove(component)
end
end
# Step 2: Leaf Classes
class Dot
include GraphicComponent
def draw
"Drawing a dot."
end
end
class Line
include GraphicComponent
def draw
"Drawing a line."
end
end
# Step 3: Composite Class
class CompoundGraphic
include GraphicComponent
def initialize
@children = []
end
def draw
@children.map(&:draw).join("\n")
end
def add(component)
@children << component
end
def remove(component)
@children.delete(component)
end
end
# Step 4: Client Code
compound_graphic = CompoundGraphic.new
compound_graphic.add(Dot.new)
compound_graphic.add(Line.new)
puts compound_graphic.draw
Output:
Drawing a dot. Drawing a line.
Explanation:
1. GraphicComponent serves as the common interface for both simple (Leaf) and complex (Composite) objects.
2. Dot and Line are leaf nodes. They don't have children and they implement the draw method.
3. CompoundGraphic is the composite node. It can have children (both Leaf and Composite), and its drawing method delegates the drawing operation to its children.
4. The client code demonstrates how to create composite structures and treat single and composite objects uniformly.
7. When to use?
Use the Composite Design Pattern when:
1. You need to represent part-whole hierarchies of objects.
2. You want clients to be able to ignore the difference between individual objects and compositions.
3. You want a unified interface for individual and composed objects.
Comments
Post a Comment