Composite Design Pattern in PHP

1. Definition

The Composite Design Pattern is a structural pattern that lets you compose objects into tree structures to represent whole-part hierarchies. In this pattern, both individual objects and their composites share the same interface, making it easier for clients to treat them uniformly.

2. Problem Statement

Imagine having to deal with objects and collections of objects. If both are treated differently, it would be challenging for clients to interact with them in a consistent manner. This results in a lot of conditional statements and a complex, hard-to-maintain codebase.

3. Solution

The Composite Pattern offers a solution where both individual objects and their composites share the same interface. Thus, clients can treat single objects and compositions uniformly, simplifying the code.

4. Real-World Use Cases

1. Graphic systems where shapes can be composed into complex diagrams.

2. Organizational structures where individuals form departments and departments form organizations.

3. File and directory systems.

5. Implementation Steps

1. Define a component interface with methods that are common to both simple and complex elements.

2. Create leaf elements that implement the component interface.

3. Create composite objects that also implement the component interface, and can contain leaf or other composite objects.

4. Clients then use the component interface to interact with both individual objects and their composites.

6. Implementation in PHP

<?php
// Step 1: Component Interface
interface Component {
    public function operation(): string;
}
// Step 2: Leaf
class Leaf implements Component {
    public function operation(): string {
        return "Leaf";
    }
}
// Step 3: Composite
class Composite implements Component {
    private $children = [];
    public function add(Component $component): void {
        $this->children[] = $component;
    }
    public function operation(): string {
        $results = [];
        foreach ($this->children as $child) {
            $results[] = $child->operation();
        }
        return "Branch(" . implode("+", $results) . ")";
    }
}
// Client code
$leaf1 = new Leaf();
$leaf2 = new Leaf();
$composite = new Composite();
$composite->add($leaf1);
$composite->add($leaf2);
echo $composite->operation(); // Outputs: Branch(Leaf+Leaf)
?>

Output:

Branch(Leaf+Leaf)

Explanation:

The Component interface defines a standard interface for all concrete objects. The Leaf class represents individual objects, and the Composite class represents complex objects that can contain Leafs or other Composites.

The client interacts with the Composite and Leaf objects uniformly through the Component interface. In the example above, the client creates two leaf objects and one composite, and then adds the leaves to the composite. When calling the operation method on the composite, it combines the results of the same method called on all its children.

7. When to use?

The Composite Pattern is useful when:

1. You want to represent hierarchies of objects as tree structures.

2. You want clients to ignore the difference between compositions of objects and individual objects.

3. Simplifying the client code by treating individual and composite objects uniformly.


Comments