Компонентный подход в программировании

       

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


Название. Шаблонный метод (template method).

Назначение. Фиксация общей схемы некоторого алгоритма, имеющего много вариантов, с предоставлением возможности реализовать эти варианты за счет переопределения отдельных его шагов, без изменения схемы в целом. При использовании этой идиомы нужно принимать во внимание следующие факторы:

Действующие силы.

  • Инвариантные части алгоритма нужно записать один раз и переиспользовать, изменяя только варьирующиеся шаги и элементы.
  • Иногда такие инвариантные части еще нужно выделить, чтобы сделать более понятным и более удобным для сопровождения код нескольких классов, реализующих близкие по назначению методы.
  • Многие алгоритмы при их практическом использовании могут зависеть от большого числа факторов, изменяющихся гораздо чаще, чем общая схема такого алгоритма (вспомните принцип разделения политик и алгоритмов).

Решение. Общая схема алгоритма, которую нужно зафиксировать, помещается в абстрактный класс в виде метода, код которого реализует эту схему. В тех местах, где необходимо использовать какой-то варьирующийся элемент алгоритма, этот метод обращается к другому методу данного класса, который можно переопределить в классах-потомках.

Структура. Метод, реализующий основную схему алгоритма, называется шаблонным методом. Он пишется один раз в абстрактном базовом классе и не переопределяется в потомках. Методы, вызываемые им, делятся на следующие группы:

  • Конкретные операции, реализация которых известна на момент написания метода и не должна изменяться.
  • Абстрактные операции, которые представляют собой изменяемые части алгоритма. Они не имеют реализации и должны определяться в каждом классе-потомке в соответствии с теми вариациями, которые он вносит в базовый алгоритм.
  • Операции-перехватчики, или зацепки (hook operations), которые также представляют собой изменяемые элементы алгоритма, но имеют некоторую реализацию по умолчанию, записанную в базовом классе. Эти операции могут переопределяться в классах-потомках, если представляемые ими элементы алгоритма нужно изменить по сравнению с имеющейся реализацией по умолчанию.
  • Фабричные методы (factory methods), предназначенные для создания объектов, которые связаны с работой конкретного варианта алгоритма.
    Они реализуются по образцу, также называемому "фабричный метод". Суть такого метода в том, что при его вызове мы точно не знаем, объект какого конкретного класса будет создан — это зависит от текущей конфигурации системы.


Динамика. Типичный сценарий работы шаблонного метода показан на рис. 8.6. Для наглядности на этой диаграмме операции, выполняемые в одном объекте, разделены между двумя виртуальными объектами: первый представляет все действия, выполняемые в рамках абстрактного класса, определяющего шаблонный метод, а второй — те действия, которые (пере)определяются в конкретном подклассе.


увеличить изображение
Рис. 8.6.  Сценарий работы шаблонного метода

Реализация. Основные шаги реализации следующие:

  • Определить основные шаги алгоритма. Определить набор данных, которыми он пользуется.
  • Выделить среди шагов алгоритма те, которые зависят от конкретных политик. Определить для каждого такого шага абстрактный метод.
  • Выделить среди данных, которыми пользуется алгоритм, те, чья структура зависит от политик или конкретного варианта алгоритма. Определить для порождения таких данных фабричные методы, а для операций над ними — абстрактные методы. Для их представления могут понадобиться дополнительные классы, но изменяемая часть данных должна, по возможности, находиться в абстрактном классе, определяющем шаблонный метод.
  • Реализовать общую схему алгоритма в теле шаблонного метода. Выделить его элементы, используемые несколько раз или представляющие собой отдельные операции, в отдельные методы абстрактного класса.
  • Определить, какие дополнительные возможности по вариации поведения алгоритма могут понадобиться. Определить для таких возможностей методы-перехватчики.
  • Определить несколько наиболее часто используемых вариантов алгоритма. Реализовать их в виде подклассов определяющего шаблонный метод класса, определив в них методы, которые представляют абстрактные операции, и, если это необходимо, переопределив методы-перехватчики.


Следствия применения образца.



Достоинства:

  • Общая часть алгоритма реализуется явно и может быть легко переиспользована.
  • Изменяемые части алгоритма могут варьироваться удобным образом, не влияя друг на друга и давая в результате различные его модификации.
  • Алгоритм может быть параметризован большим набором политик, для каждой из которых возможна реализация по умолчанию.


Недостатки:

  • Снижение понятности кода за счет сложного потока управления.
  • Снижение производительности в случае большого числа параметров, из которых в каждом конкретном варианте алгоритма используется лишь несколько.


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

Жизненный цикл компонентов EJB реализован в виде шаблонного метода, в котором абстрактной операцией служит создание объектов данного компонента. Имеется также несколько операций-перехватчиков, позволяющих разработчику компонента специфическим образом обрабатывать переход компонента из одного состояния в другое.

Другой пример — реализация метода start(), запускающего отдельный поток в Java. Инструкции, выполняемые в рамках потока, помещаются в метод run() объекта класса Thread или класса, реализующего интерфейс Runnable. Этот метод служит операцией-перехватчиком для метода start() — реализация метода run() по умолчанию ничего не делает.


Содержание раздела