printПаттерны поведения

printШаблонный метод

Template Method

Назначение
Шаблонный метод определяет основу алгоритма и позволяет подклассам переопределить некоторые шага алгоритма, не изменяя его структуру в целом.

Результаты
Шаблонные методы – один из фундаментальных приемов повторного использования кода. Они особенно важны в библиотеках классов, поскольку предоставляют возможность вынести общее поведение в библиотечные классы. Шаблонные методы приводят к инвертированной структуре кода, которую иногда называют принципом Голливуда, подразумевая часто употребляемую в этой киноимперии фразу «Не звоните нам, мы сами позвоним». В данном случае это означает, что родительский класс вызывает операции подкласса, а не наоборот.
Шаблонные методы вызывают операции следующих видов:
1) конкретные операции из производных классов;
2) конкретные операции из базового класса, то есть операции, полезные всем подклассам;
3) примитивные операции, то есть абстрактные операции;
4) фабричные методы (см. паттерн фабричный метод);
5) операции-зацепки (hook operations), реализующие поведение по умолчанию, которое может быть расширено в подклассах. Часто такая операция по умолчанию не делает ничего.
Важно, чтобы в шаблонном методе четко различались операции-зацепки, которые можно замещать, и абстрактные операции, которые нужно замещать. Чтобы повторно использовать абстрактный класс с максимальной эффективностью, авторы подклассов должны понимать, какие операции предназначены для замещения. Подкласс может расширить поведение некоторой операции, заместив ее и явно вызвав эту операцию из родительского класса.

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

Реализация
// Абстрактный класс определяет абстрактные примитивные операции, 
// замещаемые в конкретных подклассах для реализации шагов алгоритма
// и реализует шаблонный метод, определяющий скелет алгоритма
class AbstractClass {
public:
  void TemplateMethod() 
  { ...
    PrimitiveOperarion1();
    ...
    PrimitiveOperarion2();
    ...
  }
  virtual void PrimitiveOperation1() {}
  virtual void PrimitiveOperation2()=0;
};
// Конкретный класс реализует примитивные операции
class ConcreteClass: public AbstractClass {
public:
  void PrimitiveOperation1();
  void PrimitiveOperation2();
};
loading