Компонувальник

Аналогія

Кожна компанія складається із співробітників. У кожного співробітника є ті самі властивості: зарплата, обов'язки, звітність перед кимось, субординація...

Коротко

Шаблон «Компонувальник» дозволяє клієнтам обробляти окремі об'єкти в єдиному порядку.

Вікіпедія

Шаблон «Компоновщик» описує загальний порядок обробки групи об'єктів, немов це одиночний екземпляр об'єкта. Суть шаблону — компонування об'єктів у деревоподібну структуру уявлення ієрархії від приватного до целому. Шаблон дозволяє клієнтам однаково звертатися до окремих об'єктів та груп об'єктів.

Приклад

Ось різні типи працівників:

interface Employee
{
    public function __construct(string $name, float $salary);
    public function getName(): string;
    public function setSalary(float $salary);
    public function getSalary(): float;
    public function getRoles(): array;
}

class Developer implements Employee
{
    protected $salary;
    protected $name;

    public function __construct(string $name, float $salary)
    {
        $this->name = $name;
        $this->salary = $salary;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setSalary(float $salary)
    {
        $this->salary = $salary;
    }

    public function getSalary(): float
    {
        return $this->salary;
    }

    public function getRoles(): array
    {
        return $this->roles;
    }
}

class Designer implements Employee
{
    protected $salary;
    protected $name;

    public function __construct(string $name, float $salary)
    {
        $this->name = $name;
        $this->salary = $salary;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setSalary(float $salary)
    {
        $this->salary = $salary;
    }

    public function getSalary(): float
    {
        return $this->salary;
    }

    public function getRoles(): array
    {
        return $this->roles;
    }
}

А ось компанія, яка складається із співробітників різних типів:

class Organization
{
    protected $employees;

    public function addEmployee(Employee $employee)
    {
        $this->employees[] = $employee;
    }

    public function getNetSalaries(): float
    {
        $ netSalary = 0;

        foreach ($this->employees as $employee) {
            $netSalary += $employee->getSalary();
        }

        return $netSalary;
    }
}

Використання:

// Підготовка працівників
$ john = new Developer ( 'John Doe', 12000);
$jane = new Designer('Jane Doe', 15000);

// Включення їх у штат
$organization = new Organization();
$organization->addEmployee($john);
$organization->addEmployee($jane);

echo "Net salaries:". $organization->getNetSalaries(); // Net Salaries: 27000