PHP паттерн декоратор - пример

Ниже приведём пример реализации шаблона проектирования Декоратор, о "прозрачности" и других особенностях его использования можно прочитать здесь.

/* абстрактный класс  - общий "родитель" для всех элементов системы -
именно за счёт общего предка возможна прозрачная "замена" 
элемента декоратором*/
    abstract class Component
    {
        /* предлагаем потомкам реализовать эту операцию */
       abstract public function Operation();
    }

/* Конкретный элемент - несёт функционал
 - что-то что нужно постоянно - 
в соответствии с задумкой программиста*/
    class ConcreteComponent extends Component
    {
      public function Operation()
      {
         /*реализуем операцию - просто возвращаем строку */
         return 'I am component';
      }
    }

/* абстрактный декторар
 - наследуется от компонента (его потомок) - 
но одновременно является родителем всех декораторов - 
в его реализацию следует вложить то,
 что понадобится любому декоратору -
вне зависимости от специфики */
    abstract class Decorator extends Component
    {
      protected  $_component = null; // храним ссылку на компонент

      /* опишем процесс получения этой ссылки в конструкторе*/
      public function __construct(Component $component)
      {
         $this -> _component = $component; // запоминаем её.
      }

      /* метод для получения объекта конкретного компонента*/
      protected function getComponent()
      {
         return $this -> _component;
      }
      /*  "Проброс" операции на конкретный компонент -
        в силу наследования от общего предка "прозрачен"
        с точки зрения клиента*/
      public function Operation()
      {
          return $this -> getComponent() -> Operation();
      }
    }

/* Далее мы "запланируем" сразу два декоратора  */


    /*Итак, первый декоратор   - добавляет тэг для оформления ссылки */
    class ConcreteDecoratorA extends Decorator
    {
       public function Operation()
       {
          // возвращаем расширенный результат
          return '[a]' . parent::Operation() . '[/a]';
       }
    }

    /*второй   - делает текст "жирным" */
    class ConcreteDecoratorB extends Decorator
    {
        public function Operation()
        {
            // возвращаем расширенный результат
           return '[strong]' . parent::Operation() . '[/strong]'; 
        }
    }

    // Пример использования ("клиентский" код)
// Создаём класс элемента системы
    $Element = new ConcreteComponent();
// Создаём декоратор и параметризируем его элементом -
// именно так мы сможем расширить функционал
    $ExtendedElement = new ConcreteDecoratorA($Element);
// в силу "прозрачности" использования декоратора ничто не мешает нам
// вложить один декоратор в другой (по принципу матрёшки)
    $SuperExtendedElement = new ConcreteDecoratorB($ExtendedElement);

// посмотрим на получившийся расширенный функционал
    print $SuperExtendedElement -> Operation(); 
/*
В результате мы получим строку обрамлённую двумя парами тэгов: 
[strong][a] I am component [/a][/strong] */

Источники: