The Composite pattern is a structural design pattern that allows you to compose objects into tree-like structures to represent part-whole hierarchies. This pattern enables clients to treat individual objects and compositions of objects uniformly, allowing you to work with complex tree structures more easily.

Key Characteristics:

  • Hierarchical Structure: Allows objects to be composed into tree structures where individual objects and compositions are treated uniformly.
  • Uniformity: Clients can treat individual objects and composites in the same way.
  • Transparency: Simplifies the client code by abstracting the complexity of tree structures.

How It Works:

  1. Component: Defines the interface for all objects in the composition, both leaf and composite objects.
  2. Leaf: Implements the component interface and represents the end objects of the hierarchy, which do not have any children.
  3. Composite: Implements the component interface and stores child components. It represents the nodes in the tree structure that can have children.

Example in PHP:

  // Component Interface
interface Component {
    public function operation();
}

// Leaf Class
class Leaf implements Component {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function operation() {
        return "Leaf: " . $this->name;
    }
}

// Composite Class
class Composite implements Component {
    private $children = [];

    public function add(Component $component) {
        $this->children[] = $component;
    }

    public function remove(Component $component) {
        $this->children = array_filter($this->children, function($child) use ($component) {
            return $child !== $component;
        });
    }

    public function operation() {
        $results = [];
        foreach ($this->children as $child) {
            $results[] = $child->operation();
        }
        return "Composite:\n" . implode("\n", $results);
    }
}

// Usage
$leaf1 = new Leaf("Leaf1");
$leaf2 = new Leaf("Leaf2");

$composite = new Composite();
$composite->add($leaf1);
$composite->add($leaf2);

echo $leaf1->operation(); // Output: Leaf: Leaf1
echo $composite->operation(); 
// Output:
// Composite:
// Leaf: Leaf1
// Leaf: Leaf2
  

Explanation:

  1. Component Interface: Component defines the interface that both Leaf and Composite classes will implement.
  2. Leaf: The Leaf class represents end objects in the hierarchy. It does not have any children and implements the Component interface.
  3. Composite: The Composite class represents nodes in the hierarchy that can have children. It also implements the Component interface and provides methods to add and remove child components.

Benefits:

  • Uniformity: Treats individual objects and compositions uniformly, simplifying the client code.
  • Flexibility: Allows you to build complex tree structures dynamically.
  • Transparency: Clients interact with the entire hierarchy through a single interface.

Use Cases:

  • Graphic Systems: For representing tree structures such as graphics or document objects.
  • File Systems: To model directory structures where both files and directories are treated uniformly.

The Composite pattern is useful for managing complex hierarchical structures, allowing you to handle individual objects and compositions in a consistent and flexible manner.