Книга: Экстремальное программирование. Разработка через тестирование

Шаблонный метод (Template Method)

Шаблонный метод (Template Method)

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

В программировании существует огромное количество классических последовательностей:

• ввод – обработка – вывод;

• отправить сообщение – принять ответ;

• прочитать команду – вернуть результат.

Нам хотелось бы четко и понятно обозначить универсальность этих последовательностей и при этом обеспечить возможность варьирования реализаций каждого из отдельных этапов.

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

TestCase

public void runBare() throws Throwable {

setUp();

try {

runTest();

}

finally {

tearDown();

}

}

Классы, производные от TestCase, могут реализовать setUp(), runTest() и tearDown() так, как им этого хочется.

При использовании шаблона «Шаблонный метод» (Template Method) возникает вопрос: надо ли создавать для подметодов реализации по умолчанию? В TestCase.runBare() все три подметода обладают реализациями по умолчанию:

• методы setUp() и tearDown() не выполняют никаких операций;

• метод runTest() динамически обнаруживает и запускает все тестовые методы, исходя из имени класса-теста.

Если общая последовательность не имеет смысла, когда не определен один из ее этапов, вы должны отметить это, воспользовавшись любой подходящей возможностью используемого вами языка программирования:

• в Java можно объявить подметод абстрактным;

• в Smalltalk создайте реализацию метода, которая генерирует ошибку SubclassResponsibility.

Я не рекомендую изначально проектировать код так, чтобы в нем использовался шаблонный метод. Лучше всего формировать шаблонные методы исходя из накопленного опыта. Каждый раз, когда я говорю себе: «Ага, вот последовательность, а вот – детали реализации», – позднее я всегда обнаруживаю, что мне приходится переделывать созданный мною шаблонный метод, заново перетасовывая код между общим и частным.

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

Оглавление книги


Генерация: 1.119. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз