Patterns. Паттерн Template Method (реалізація схеми)

Паттерн Template Method (реалізація схеми)


Зміст


1. Загальні відомості. Призначення. Учасники паттерну

Паттерн Template Method (Шаблонний метод) належить до паттернів поведінки класів. Шаблонний метод визначає кроки алгоритму і дозволяє підкласам визначати деякі з цих кроків. При цьому структура самого алгоритму не змінюється.

Суть шаблону полягає в тому, що в деякий абстрактний клас поміщаються

  • методи (операції) які описують алгоритм. Ці методи називаються шаблонними методами. У своєму тілі вони звертаються до методів, які реалізовані в успадкованих класах;
  • методи, які заміщаються в успадкованих класах. Ці методи визначають потрібну поведінку.

Структура (діаграма класів) паттерну Template Method наведена на рисунку 1.

Паттерн Template Method (Шаблонний метод). Діаграма класів

Рисунок 1. Структура (діаграма класів) паттерну Template Method

Учасниками паттерну є наступні елементи (див. рисунок 1).

  1. AbstractClass – абстрактний клас, який визначає:
  • перелік примітивних методів (операцій), які заміщаються у конкретних підкласах;
  • один або декілька шаблонних методів, які визначають кроки (основу) алгоритму. Шаблонний метод викликає примітивні методи, які реалізовані в AbstractClass або в інших об’єктах.
  1. ConcreteClass – конкретний клас. Реалізує примітивні методи (операції), які виконують кроки алгоритму. Реалізація кожного кроку визначається особливостями підкласу.

 

2. Випадки застосування

Паттерн Template Method може застосовуватись у наступних випадках:

  • коли потрібно реалізувати постійні кроки алгоритму, кожен з яких (кроків) змінюється в залежності від реалізації у підкласах;
  • коли в одному класі потрібно виділити спільну для всіх підкласів поведінку з метою уникнення дублювання коду. При такому підході, спочатку, виділяються відмінності в коді, а потім ці відмінності реалізуються в успадкованих класах;
  • коли виникає необхідність у виклику так званих операцій-зачіпок (hooks) у визначених точках.

 

3. Приклад реалізації структури паттерну на мові C++

У нижченаведеному коді на мові C++ реалізовано паттерн Template Method.

#include <iostream>
using namespace std;

// Паттерн Template Method - реалізація схеми
class AbstractClass abstract
{
public:
  // Шаблонний метод - викликає методи
  // PrimitiveOperation1(), PrimitiveOperation2()
  void TemplateMethod()
  {
    // реалізація алгоритму виклику
    PrimitiveOperation1();
    PrimitiveOperation2();
  }

  virtual void PrimitiveOperation1() = 0;
  virtual void PrimitiveOperation2() = 0;
};

class ConcreteClass : public AbstractClass
{
public:
  // Конкретні реалізації операцій
  void PrimitiveOperation1()
  {
    cout << "ConcreteClass::PrimitiveOperation1()" << endl;
  }

  void PrimitiveOperation2()
  {
    cout << "ConcreteClass::PrimitiveOperation2()" << endl;
  }
};

int main()
{
  // Створити екземпляр конкретного класу
  AbstractClass* p = new ConcreteClass();

  // Викликати шаблонний метод
  p->TemplateMethod();

  // Звільнити пам'ять
  if (p)
    delete p;
}

 

4. Результати

Для паттерну Template Method можна виділити наступні результати.

  1. Паттерн дозволяє винести загальну поведінку в бібліотечні класи.
  2. Структура коду в паттерні є інвертованою. Це означає, що базовий клас викликає методи підкласу, а не навпаки.

Методи, що викликаються з базового класу, можуть бути таких видів (див. рисунок 1):

  • конкретні методи (операції). Це методи, що викликаються з класів клієнта або з класу ConcreteClass. На рисунку 1 такими класами є PrimitiveOperation1() та PrimitiveOperation2();
  • конкретні методи з класу AbstractClass. Це є методи, які спільно використовуються усіма підкласами. На рисунку 1 таким методом є TemplateMethod();
  • примітивні (абстрактні) методи;
  • фабричні методи. Більш детально про фабричні методи можна подивитись тут (паттерн Factory Method);
  • методи-зачіпки (операції-зачіпки, hooks operations). Це методи, що реалізують поведінку за замовчуванням, яка допускає зміну в успадкованих класах. Важливо, щоб у паттерні повинні бути чітко відділені операції-зачіпки від абстрактних операцій. Операції-зачіпки можна перевизначати або не перевизначати. Абстрактні операції обов’язково потрібно перевизначати.

 

5. Операція-зачіпка (hook operation). Приклад на C++

 

// Паттерн Template Method
// Приклад операції-зачіпки (hook operation)
// Базовий клас - реалізує метод за замовчуванням
class BaseClass
{
public:
  // метод за замовчуванням не виконує
  // ніякої роботи
  void HookOperation()
  { }

  // Шаблонний метод
  void Operation()
  {
    // Поведінка батьківського класу ParentClass
    HookOperation();
  }
};

// Успадкований клас - робить заміщення операції
// HookOperation() базового класу
class DerivedClass : public BaseClass
{
public:
  // Тут розширення поведінки
  void HookOperation()
  {
    // виконання дій, що розширюють метод
    // базового класу
    // ...
  }
};

 

6. Особливості реалізації

Для паттерну Template Method можна виділити такі особливості реалізації.

  1. Забезпечення контролю доступу. У цьому випадку примітивні методи, які викликає шаблонний метод, можна оголосити в розділі protected (захищеними). Це дає можливість виклику цих методів тільки шаблонним методом. Так само примітивні методи, які обов’язково мають бути заміщеними, оголошуються як чисто віртуальні функції.
  2. Скорочення кількості примітивних методів для клієнта. Примітивні методи (операції) заміщаються в підкласах. Бажано, по можливості, мінімізувати кількість примітивних методів для клієнта.
  3. Узгодження імен. Тут мається на увазі встановлення додаткового префіксу до імен методів, які потрібно замістити.

 


Споріднені теми