Шаблон метода шаблона

Поведенческий шаблон проектирования в объектно-ориентированном программировании

В объектно-ориентированном программировании метод шаблона является одним из поведенческих шаблонов проектирования, определенных Гаммой и др. [1] в книге Шаблоны проектирования . Метод шаблона является методом в суперклассе, обычно абстрактном суперклассе, и определяет скелет операции в терминах ряда высокоуровневых шагов. Эти шаги сами по себе реализуются дополнительными вспомогательными методами в том же классе, что и метод шаблона .

Вспомогательные методы могут быть либо абстрактными методами , в этом случае подклассы должны предоставлять конкретные реализации, либо методами-ловушками , которые имеют пустые тела в суперклассе. Подклассы могут (но не обязаны) настраивать операцию , переопределяя методы-ловушки. Целью метода-шаблона является определение общей структуры операции, позволяя подклассам уточнять или переопределять определенные шаги. [2]

Обзор

Этот шаблон состоит из двух основных частей:

  • «Шаблонный метод» реализован как метод в базовом классе (обычно абстрактном классе ). Этот метод содержит код для частей общего алгоритма, которые являются инвариантными. Шаблон гарантирует, что общий алгоритм всегда соблюдается. [1] В шаблонном методе части алгоритма, которые могут изменяться, реализуются путем отправки сообщений себе, которые запрашивают выполнение дополнительных вспомогательных методов. В базовом классе этим вспомогательным методам предоставляется реализация по умолчанию или вообще не предоставляется никакой (то есть они могут быть абстрактными методами).
  • Подклассы базового класса «заполняют» пустые или «вариативные» части «шаблона» с помощью определенных алгоритмов, которые различаются от одного подкласса к другому. [3] Важно, чтобы подклассы не переопределяли сам метод шаблона .

Во время выполнения алгоритм, представленный шаблонным методом, выполняется путем отправки шаблонного сообщения экземпляру одного из конкретных подклассов. Через наследование шаблонный метод в базовом классе начинает выполняться. Когда шаблонный метод отправляет сообщение самому себе, запрашивая один из вспомогательных методов, сообщение будет получено конкретным подэкземпляром. Если вспомогательный метод был переопределен, будет выполнена переопределяющая реализация в подэкземпляре; если он не был переопределен, будет выполнена унаследованная реализация в базовом классе. Этот механизм гарантирует, что общий алгоритм каждый раз следует тем же шагам, позволяя деталям некоторых шагов зависеть от того, какой экземпляр получил исходный запрос на выполнение алгоритма.

Этот шаблон является примером инверсии управления , поскольку высокоуровневый код больше не определяет, какие алгоритмы следует запускать; вместо этого во время выполнения выбирается алгоритм более низкого уровня.

Некоторые из сообщений, отправляемых шаблонным методом, могут быть методами- перехватчиками . Эти методы реализованы в том же базовом классе, что и шаблонный метод, но с пустыми телами (т. е. они ничего не делают). Методы-перехватчики существуют для того, чтобы подклассы могли переопределять их и, таким образом, настраивать действие алгоритма без необходимости переопределять сам шаблонный метод. Другими словами, они предоставляют «крючок», на который «подвешиваются» реализации вариантов.

Структура

Диаграмма классов UML

Пример диаграммы классов UML для шаблона проектирования «Шаблонный метод». [4]

В приведенной выше диаграмме классов UML определяется операция , которая определяет скелет (шаблон) поведенияAbstractClasstemplateMethod()

  • реализация инвариантных частей поведения и
  • отправка себе сообщений primitive1()и primitive2(), которые, поскольку они реализованы в SubClass1, позволяют этому подклассу предоставлять вариантную реализацию этих частей алгоритма.
Метод шаблона в LePUS3. [5]

Использование

Метод шаблона используется в фреймворках, где каждый реализует инвариантные части архитектуры домена, предоставляя при этом методы-ловушки для настройки. Это пример инверсии управления . Метод шаблона используется по следующим причинам. [3]

  • Это позволяет подклассам реализовывать различное поведение (путем переопределения методов-хуков). [6]
  • Это позволяет избежать дублирования в коде: общий рабочий процесс алгоритма реализуется один раз в шаблонном методе абстрактного класса, а необходимые вариации реализуются в подклассах. [6]
  • Он контролирует точку(ы), в которой разрешена специализация. Если бы подклассы просто переопределяли метод шаблона, они могли бы вносить радикальные и произвольные изменения в рабочий процесс. Напротив, переопределяя только методы-ловушки, можно изменить только определенные детали рабочего процесса, [6] а общий рабочий процесс останется нетронутым.

Использовать с генераторами кода

Шаблон шаблона полезен при работе с автоматически сгенерированным кодом. Проблема работы с сгенерированным кодом заключается в том, что изменения в исходном коде приведут к изменениям в сгенерированном коде; если в сгенерированный код были внесены рукописные изменения, они будут утеряны. Как же тогда следует настраивать сгенерированный код?

Шаблон Template предоставляет решение. Если сгенерированный код следует шаблону метода шаблона, то весь сгенерированный код будет абстрактным суперклассом. При условии, что рукописные настройки ограничены подклассом, генератор кода может быть запущен снова без риска перезаписи этих изменений. При использовании с генерацией кода этот шаблон иногда называют шаблоном разрыва генерации . [7]

Пример на С++

Данная реализация C++14 основана на реализации, существовавшей до C++98 и описанной в книге.

Шаблон метода шаблона Cpp UML.svg

#include <iostream> #include <память>  class View { // AbstractClass public : // определяет абстрактные примитивные операции, которые определяются конкретными подклассами для реализации шагов алгоритма. virtual void doDisplay () {} // реализует шаблонный метод, определяющий скелет алгоритма. Шаблонный метод вызывает примитивные операции, а также операции, определенные в AbstractClass или других объектах. 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 // реализует примитивные операции для выполнения шагов алгоритма, специфичных для подкласса. void doDisplay () override { // визуализирует содержимое представления std :: cout << "MyView::doDisplay \n " ; } };                int main () { // Умные указатели предотвращают утечки памяти std :: unique_ptr < View > myview = std :: make_unique < MyView > (); myview -> display (); }        

Вывод программы:

Вид :: setFocus MyView :: doDisplay Вид :: resetFocus

Смотрите также

Ссылки

  1. ^ ab Gamma, Erich ; Helm, Richard ; Johnson, Ralph ; Vlissides, John (1994). "Template Method". Design Patterns . Addison-Wesley. стр. 325–330. ISBN 0-201-63361-2.
  2. ^ Фримен, Эрик; Фримен, Элизабет; Сьерра, Кэти; Бейтс, Берт (2004). Хендриксон, Майк; Лукидес, Майк (ред.). Head First Design Patterns (мягкая обложка) . Том 1. O'REILLY. С. 289, 311. ISBN 978-0-596-00712-6. Получено 12.09.2012 .
  3. ^ ab "Шаблон метода проектирования". Источник Создание - обучение ИТ-специалистов . Получено 2012-09-12 . Шаблон метода используется в фреймворках.
  4. ^ "Шаблонный метод проектирования - Структура". w3sDesign.com . Получено 2017-08-12 .
  5. ^ Легенда LePUS3. Получено с http://lepus.org.uk/ref/legend/legend.xml.
  6. ^ abc Chung, Carlo (2011). Pro Objective-C Design Patterns for iOS . Беркли, Калифорния: Apress. стр. 266. ISBN 978-1-4302-3331-2.
  7. ^ Влиссидес, Джон (1998-06-22). Штриховка узора: прикладные шаблоны проектирования. Addison-Wesley Professional. стр. 85–101. ISBN 978-0201432930.
  • Шесть распространенных вариантов использования шаблона
  • Шаблон Метода Проектирования Шаблон
Получено с "https://en.wikipedia.org/w/index.php?title=Шаблон_метода_шаблона&oldid=1237887016"