Шаблонный метод — это популярный поведенческий шаблон проектирования. При его помощи можно задать некоторое поведение в методе абстрактного класса, но при этом оставить детали реализации на классы-наследники. Проще говоря, в контексте языка программирования Java шаблонный метод — это метод абстрактного класса или метод по умолчанию интерфейса, задающий общее поведение, но опирающийся на другие абстрактные методы. Шаблонный метод наряду с шаблоном проектирования «Стратегия» часто применяется при реализации инверсии управления.
Демонстрируя пример реализации шаблона проектирования «Декоратор», я использовал и шаблонный метод в классе CachingFindTaskByIdDecorator
:
Метод findTaskById
в данном случае реализует шаблон проектирования «Шаблонный метод», он задаёт некоторое поведение, но оставляет детали реализации, поиск и сохранение задачи в кэше, на классы-наследники.
Тестирование шаблонного метода
Как правило, тестирование шаблонного метода происходит при тестировании классов-наследников. Однако возможна ситуация, когда классов-наследников у абстрактного класса, содержащего шаблонный метод, нет наследников в рамках проекта. Происходит это в случаях, когда вы разрабатываете какой-то фреймворк или библиотеку и хотите, чтобы реализацию этого абстрактного класса предоставлял пользователь вашей библиотеки. В этом случае всё же желательно написать тест для абстрактного класса, содержащего шаблонный метод. Сделать это можно двумя способами: при помощи тестовой реализации абстрактного класса или при помощи фреймворков для создания объектов-имитаций, например Mockito.
В первом случае вам необходимо создать в директории тестовых классов максимально простой класс, реализующий тестируемый абстрактный класс. Для CachingFindTaskByIdDecorator
тестовая реализация может выглядеть следующим образом:
Теперь необходимо написать тест для TestingCachingFindTaskByIdDecorator
:
Я не сторонник создания классов специально для тестов вроде TestingCachingFindTaskByIdDecorator
, поэтому предлагаю рассмотреть второй вариант. В нём необходимо будет создать объект-имитацию CachingFindTaskByIdDecorator
, но использовать реальный метод findTaskById
. Кроме этого при создании объекта-имитации потребуется использовать правильный конструктор для передачи декорируемого объекта.
Тест будет выглядеть следующим образом:
Как видно из получившегося кода, можно обойтись без тестовых реализаций абстрактных классов.
Применяйте шаблонный метод для реализации общего поведения в абстрактных классах для придания большей гибкости вашему коду.