Шаблон метода шаблона - Template method pattern

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

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

Обзор

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

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

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

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

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

Структура

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

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

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

  • реализация инвариантных частей поведения и
  • отправка в я сообщения примитив1 () и примитив2 () , которые, поскольку они реализованы в Подкласс1 , позволяет этому подклассу предоставлять вариант реализации этих частей алгоритма.
Шаблонный метод в LePUS3.[5]

Применение

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

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

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

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

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

Пример PHP

Абстрактные класс Игра{    Абстрактные защищенный функция инициализировать();    Абстрактные защищенный функция startPlay();    Абстрактные защищенный функция endPlay();    / ** Шаблонный метод * /    общественный окончательный функция играть в()    {        /** Примитивный */        $ это->инициализировать();        /** Примитивный */        $ это->startPlay();        /** Примитивный */        $ это->endPlay();    }}класс Марио расширяет Игра{    защищенный функция инициализировать()    {        эхо «Игра Марио инициализирована! Начни играть»., PHP_EOL;    }    защищенный функция startPlay()    {        эхо «Игра Марио началась. Наслаждайтесь игрой!», PHP_EOL;    }    защищенный функция endPlay()    {        эхо «Игра Марио окончена!», PHP_EOL;    }}класс Танковый бой расширяет Игра{    защищенный функция инициализировать()    {        эхо «Игра Tankfight инициализирована! Начни играть»., PHP_EOL;    }    защищенный функция startPlay()    {        эхо «Игра Tankfight началась. Наслаждайтесь игрой!», PHP_EOL;    }    защищенный функция endPlay()    {        эхо "Игра Tankfight завершена!", PHP_EOL;    }}$ игра = новый Танковый бой();$ игра->играть в();$ игра = новый Марио();$ игра->играть в();

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

использованная литература

  1. ^ а б Гамма, Эрих; Хелм, Ричард; Джонсон, Ральф; Влиссидес, Джон (1994). «Шаблонный метод». Шаблоны проектирования. Эддисон-Уэсли. стр.325–330. ISBN  0-201-63361-2.
  2. ^ Фриман, Эрик; Фриман, Элизабет; Сьерра, Кэти; Бейтс, Берт (2004). Хендриксон, Майк; Лукидес, Майк (ред.). Шаблоны проектирования Head First (мягкая обложка). 1. О'РЕЙЛИ. С. 289, 311. ISBN  978-0-596-00712-6. Получено 2012-09-12.
  3. ^ а б «Шаблон проектирования метода шаблона». Source Making - обучение ИТ-специалистов. Получено 2012-09-12. Шаблонный метод широко используется во фреймворках.
  4. ^ «Шаблон проектирования шаблонного метода - структура». w3sDesign.com. Получено 2017-08-12.
  5. ^ LePUS3 легенда. Полученное из http://lepus.org.uk/ref/legend/legend.xml.
  6. ^ а б c Чанг, Карло (2011). Шаблоны проектирования Pro Objective-C для iOS. Беркли, Калифорния: Апресс. п. 266. ISBN  978-1-4302-3331-2.
  7. ^ Влиссидес, Джон (1998-06-22). Штриховка по образцу: применение шаблонов проектирования. Эддисон-Уэсли Профессионал. С. 85–101. ISBN  978-0201432930.

внешние ссылки