printСтруктурирующие паттерны

printДекоратор

Decorator

Назначение
Динамически добавляет объекту новые обязанности. Является гибкой альтернативой порождению подклассов с целью расширения функциональности.

Результаты
1. Паттерн декоратор позволяет более гибко добавлять объекту новые обязанности, чем было бы возможно в случае простого наследования. Декоратор может добавлять и удалять обязанности во время выполнения программы. Кроме того, применение нескольких декораторов к одному компоненту позволяет произвольным образом сочетать обязанности или добавить одно и то же свойство дважды.
2. Декоратор позволяет добавлять новые обязанности по мере необходимости и избежать перегруженных функциями классов ни верхних уровнях иерархии. Нетрудно также определять новые виды декораторов независимо от классов, которые они расширяют, даже если первоначально такие расширения не планировались.
3. Декоратор действует как прозрачное обрамление. Но декорированный компонент все же не идентичен исходному.
4. При использовании в проекте паттерна декоратор нередко получается система, составленная из большого числа мелких объектов, которые похожи друг на друга и различаются только способом взаимосвязи, а не классом и не значениями своих внутренних переменных. Хотя проектировщик, разбирающийся в устройстве такой системы, может легко настроить ее, но изучать и отлаживать ее очень тяжело.

Структура
14679.png

Реализация
// Компонент определяет интерфейс для объектов
class Component {
public:
  virtual void Operation()=0;
};
// Конкретный компонент определяет класс объектов, 
// на который возлагаются дополнительные обязанности
class ConcreteComponent: public Component {
public:
  void Operation();
};
// Декоратор хранит указатель на объект Component 
// и определяет интерфейс, соответствующий интерфейсу Component
class Decorator: public Component {
protected:
  Component *c;
public:
  void Operation() { c->Operation(); }
};
// Конкретный декоратор добавляет дополнительные обязанности компоненту
class Decorator1: public Decorator {
  int data;
public:
  void AddedAction();
  void Operation() { Decorator::Operation(); AddedAction(); }
};
loading