Шаблон метода шаблона
![]() | Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( Март 2012 г. ) |
В объектно-ориентированном программировании метод шаблонов является одним из шаблонов поведенческого проектирования, выявленных Гаммой и др. [1] в книге « Шаблоны проектирования» . Метод шаблона — это метод суперкласса, обычно абстрактного суперкласса, который определяет скелет операции в виде ряда шагов высокого уровня. Эти шаги сами по себе реализуются дополнительными вспомогательными методами в том же классе, что и метод шаблона .
Вспомогательные методы могут быть либо абстрактными методами , и в этом случае подклассы необходимы для предоставления конкретных реализаций, либо методами-перехватчиками , которые имеют пустые тела в суперклассе. Подклассы могут (но не обязаны) настраивать операцию, переопределяя методы-перехватчики. Целью метода шаблона является определение общей структуры операции, позволяя при этом подклассам уточнять или переопределять определенные шаги. [2]
Обзор [ править ]
Этот шаблон состоит из двух основных частей:
- «Метод шаблона» реализован как метод базового класса (обычно абстрактного класса ). Этот метод содержит код для инвариантных частей общего алгоритма. Шаблон гарантирует, что общий алгоритм всегда будет соблюдаться. [1] В шаблонном методе части алгоритма, которые могут различаться , реализуются путем отправки собственных сообщений, запрашивающих выполнение дополнительных вспомогательных методов. В базовом классе этим вспомогательным методам предоставляется реализация по умолчанию или не предоставляется вообще (то есть они могут быть абстрактными методами).
- Подклассы базового класса «заполняют» пустые или «вариантные» части «шаблона» конкретными алгоритмами, которые варьируются от одного подкласса к другому. [3] Важно, чтобы подклассы не переопределяли сам метод шаблона .
Во время выполнения алгоритм, представленный методом шаблона, выполняется путем отправки сообщения шаблона экземпляру одного из конкретных подклассов. Благодаря наследованию начинает выполняться метод шаблона в базовом классе. Когда метод шаблона отправляет сообщение самому себе, запрашивая один из вспомогательных методов, сообщение будет получено конкретным подэкземпляром. Если вспомогательный метод был переопределен, будет выполнена переопределяющая реализация в подэкземпляре; если оно не было переопределено, будет выполнена унаследованная реализация в базовом классе. Этот механизм гарантирует, что весь алгоритм каждый раз выполняет одни и те же шаги, в то же время позволяя деталям некоторых шагов зависеть от того, какой экземпляр получил исходный запрос на выполнение алгоритма.
Этот шаблон является примером инверсии управления , поскольку код высокого уровня больше не определяет, какие алгоритмы запускать; вместо этого во время выполнения выбирается алгоритм более низкого уровня.
Некоторые из собственных сообщений, отправляемых методом шаблона, могут быть перехватчиками методов. Эти методы реализованы в том же базовом классе, что и метод шаблона, но с пустыми телами (т. е. они ничего не делают). Методы-перехватчики существуют для того, чтобы подклассы могли их переопределять и, таким образом, точно настраивать действие алгоритма без необходимости переопределять сам метод шаблона. Другими словами, они предоставляют «крючок», на который можно «подвесить» варианты реализации.
Структура [ править ]
Диаграмма классов UML [ править ]

На приведенной выше UML классов диаграмме AbstractClass
определяет templateMethod()
операция, определяющая скелет (шаблон) поведения посредством
- реализацию инвариантных частей поведения и
- отправка себе сообщений
primitive1()
иprimitive2()
, которые, поскольку они реализованы вSubClass1
, позволить этому подклассу предоставить вариант реализации этих частей алгоритма.

Использование [ править ]
Метод шаблона используется в средах, каждая из которых реализует инвариантные части архитектуры предметной области, предоставляя при этом методы перехвата для настройки. Это пример инверсии управления . Шаблонный метод используется по следующим причинам. [3]
- Он позволяет подклассам реализовывать различное поведение (путем переопределения методов-перехватчиков). [6]
- Это позволяет избежать дублирования кода: общий рабочий процесс алгоритма реализуется один раз в шаблонном методе абстрактного класса, а необходимые вариации реализуются в подклассах. [6]
- Он контролирует точку(и), в которых разрешена специализация. Если бы подклассы просто переопределили метод шаблона, они могли бы внести радикальные и произвольные изменения в рабочий процесс. Напротив, переопределяя только методы-перехватчики, можно изменить только определенные детали рабочего процесса. [6] и общий рабочий процесс остается нетронутым.
Использовать с генераторами кода [ править ]
Шаблон шаблона полезен при работе с автоматически сгенерированным кодом. Проблема работы со сгенерированным кодом состоит в том, что изменения в исходном коде приведут к изменениям в сгенерированном коде; если в сгенерированный код были внесены рукописные изменения, они будут потеряны. Как же тогда следует кастомизировать сгенерированный код?
Шаблон «Шаблон» предлагает решение. Если сгенерированный код соответствует шаблону шаблонного метода, весь сгенерированный код будет абстрактным суперклассом. При условии, что написанные вручную настройки ограничены подклассом, генератор кода можно запустить снова без риска перезаписи этих изменений. При использовании с генерацией кода этот шаблон иногда называют шаблоном разрыва поколений . [7]
Пример C++ [ править ]
Эта реализация C++14 основана на реализации до C++98, описанной в книге.
#include <iostream>
#include <memory>
class View { // AbstractClass
public:
// defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm.
virtual void doDisplay() {}
// implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.
void display() {
setFocus();
doDisplay();
resetFocus();
}
virtual ~View() = default;
private:
void setFocus() {
std::cout << "View::setFocus\n";
}
void resetFocus() {
std::cout << "View::resetFocus\n";
}
};
class MyView : public View { // ConcreteClass
// implements the primitive operations to carry out subclass-specific steps of the algorithm.
void doDisplay() override {
// render the view's contents
std::cout << "MyView::doDisplay\n";
}
};
int main() {
// The smart pointers prevent memory leaks
std::unique_ptr<View> myview = std::make_unique<MyView>();
myview->display();
}
Вывод программы
View::setFocus
MyView::doDisplay
View::resetFocus
См. также [ править ]
- Наследование (объектно-ориентированное программирование)
- Переопределение метода (программирование)
- GRASP (объектно-ориентированный дизайнер)
- Шаблон адаптера
- Паттерн стратегии
Ссылки [ править ]
- ^ Jump up to: Перейти обратно: а б Гамма, Эрих ; Хельм, Ричард ; Джонсон, Ральф ; Влиссидес, Джон (1994). «Шаблонный метод». Шаблоны проектирования . Аддисон-Уэсли. стр. 325–330 . ISBN 0-201-63361-2 .
- ^ Фриман, Эрик; Фриман, Элизабет; Сьерра, Кэти; Бейтс, Берт (2004). Хендриксон, Майк; Лукидес, Майк (ред.). Шаблоны проектирования Head First (мягкая обложка) . Том. 1. О'РЕЙЛИ. стр. 289, 311. ISBN. 978-0-596-00712-6 . Проверено 12 сентября 2012 г.
- ^ Jump up to: Перейти обратно: а б «Шаблон проектирования шаблонного метода» . Source Making - преподавание IT-специалистов . Проверено 12 сентября 2012 г.
Шаблонный метод широко используется в фреймворках.
- ^ «Шаблон проектирования шаблонного метода — структура» . w3sDesign.com . Проверено 12 августа 2017 г.
- ^ Легенда LePUS3. Получено с http://lepus.org.uk/ref/legend/legend.xml .
- ^ Jump up to: Перейти обратно: а б с Чунг, Карло (2011). Шаблоны проектирования Pro Objective-C для iOS . Беркли, Калифорния: Apress. п. 266. ИСБН 978-1-4302-3331-2 .
- ^ Влиссидес, Джон (22 июня 1998 г.). Штриховка по образцу: применение шаблонов проектирования . Аддисон-Уэсли Профессионал. стр. 85–101. ISBN 978-0201432930 .
Внешние ссылки [ править ]
