Design Pattern in PHP: Composite Pattern

The composite pattern is a partitioning design pattern. The composite pattern describes a group of objects that are treated the same way as a single instance of the same type of object.

What problems can it solve?

In the problem of our tree structure, it blurs the concepts of simple elements and complex elements. The Composite design helps client codes handle complex elements like simple elements, thereby decoupling the internal structure of client programs from complex elements. All elements defined in the combined mode share the same interface. With the help of this interface, the client code does not need to care about the specific class of the object it uses.

Implementation

Here we use the organizational structure of a company as a case. A company has many employees and departments.

Step 1: Create an abstract class as interface

abstract class Unit { 
    // leaf classes do not have add() function
    public function add(Unit $unit)
    {
    	return;
    } 

    // leaf classes do not have remove() function
    public function remove(Unit $unit)
    {
    	return;
    } 

    abstract function salary(); 
} 

Step2: create department class and employee class

/**
 * department
 */
class Department extends Unit
{
	
	private $unit = [];

	public function add(Unit $unit)
	{
		if (!in_array($unit, $this->unit, true)) {
			$this->unit[] = $unit;	
		}
	}


	public function remove(Unit $unit)
	{
		$this->unit = array_udiff(
			$this->unit, 
			[$unit],
			function ($a, $b)
			{
				return !($a === $b);
			}
		);
	}


	public function salary()
	{
		$total = 0;
		foreach ($this->unit as $item) {
			$total += $item->salary();
		}

		return $total;
	}
}

/**
 * employee
 */
class Employee extends Unit
{
	
	public function salary()
	{
		return 100;
	}
}

Step3: create some instances

$department = new Department();
$employee1 = new Employee();
$employee2 = new Employee();
$employee3 = new Employee();

// department class 
$department->add($employee1);
$department->add($employee2);
$department->add($employee3);

echo $department->salary();

Step4: run the above scripts.

$ php composite.php
300

As you can see, Department class and Employee class extend a same Unit class, so we can use salary() function on any instances.

Pros of composite pattern

  1. It is possible to clearly define hierarchical complex objects, representing all or part of the object hierarchy, making it easier to add new components.
  2. It defines a class hierarchy that includes leaf objects and container objects. Leaf objects can be combined into more complex container objects, and this container object can be combined, so that continuous recursion can form a complex tree structure.
  3. For client code, it is simple and use the composite structure or a single object in it consistently.

Cons of composite pattern

  1. The declarations of leaves class and branches class are implementation classes, not interfaces, which violates the dependency inversion principle.
  2. The data in the composite pattern is not suitable for storage in a relational database.
RSS