главная/Декораторы в PHP, подробно с примерами
PHP декораторы

Декораторы в PHP, подробно с примерами

Декораторы в программировании — это структурный шаблон проектирования, который предоставляет гибкий альтернативный способ расширения функциональности существующего объекта.

В PHP декораторы можно реализовать с использованием интерфейсов и наследования.

Допустим, у нас есть интерфейс Coffee:

interface Coffee

{
    public function getCost();
    public function getDescription();
}

Теперь создадим базовый класс SimpleCoffee, который реализует интерфейс Coffee:

class SimpleCoffee implements Coffee

{
    public function getCost()
    {
        return 10;
    }

    public function getDescription()
    {
        return 'Simple coffee';
    }
}

Чтобы расширить функциональность SimpleCoffee, мы создадим абстрактный класс декоратора CoffeeDecorator:

abstract class CoffeeDecorator implements Coffee

{
    protected $coffee;

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

    public function getCost()
    {
        return $this->coffee->getCost();
    }

    public function getDescription()
    {
        return $this->coffee->getDescription();
    }
}

Теперь мы можем создать разные декораторы, расширяющие функциональность класса SimpleCoffee.

Например, создадим декораторы для добавления молока и сахара:

class MilkDecorator extends CoffeeDecorator

{
    public function getCost()
    {
        return parent::getCost() + 2;
    }

    public function getDescription()
    {
        return parent::getDescription() . ', with milk';
    }
}

class SugarDecorator extends CoffeeDecorator

{
    public function getCost()
    {
        return parent::getCost() + 1;
    }

    public function getDescription()
    {
        return parent::getDescription() . ', with sugar';
    }
}

Теперь мы можем использовать декораторы для расширения функциональности SimpleCoffee:

$coffee = new SimpleCoffee();
echo $coffee->getCost(); // 10
echo $coffee->getDescription(); // Simple coffee

$coffee = new MilkDecorator($coffee);
echo $coffee->getCost(); // 12
echo $coffee->getDescription(); // Simple coffee, with milk

$coffee = new SugarDecorator($coffee);
echo $coffee->getCost(); // 13
echo $coffee->getDescription(); // Simple coffee, with milk, with sugar

Это позволяет избежать перегрузки классов и сохранить модульность кода.