Шаблон Template Method применяется, когда есть алгоритм, состоящий из нескольких шагов. Но в разных классах он реализуется по-разному.
Пример
Например, мы строим ледовое сооружение (ледовую горку или фигуру). Шаги такие:
- Собрать снег
- Сформировать снег
- Залить водой
- Сделать что-то еще (не обязательный шаг)
При этом ледовая фигура Снегурочки и ледовая горка отличаются шагом 2 — снег формируется для них в разную форму. А шаги 1 и 3 остаются одинаковыми.
Реализация шаблона Template Method
Мы создаем абстрактный класс, от которого будут наследоваться Снегурочка и горка. И в нем создаем Template Method (назовем его build() — построить). Он вызывает последовательно шаги алгоритма. Те шаги, которые отличаются, мы переопределяем в классах-наследниках.

Что касается шага «Сделать что-то еще» — это хук. Он создается на всякий случай и имеет пустое тело. Он тоже вызывается из Template Method. Хук добавляется, если есть необязательный шаг, то есть шаг, который нужен не всем подклассам. Например, снегурочку надо поставить на постамент, а горку — не надо. Поэтому только снегурочка переопределяет этот метод. А для горки он вызывается с пустым телом.

Итак, создадим абстрактный Класс IceStructure (ледовое сооружение), от которого будут наследоваться снегурочка и горка. Здесь build() — это Template Method:
public abstract class IceStructure {
//template method
public void build() {
collectSnow(); // шаг 1, собрать снег
formSnow(); // шаг 2, сформировать снег
fillWithWater(); // шаг 3, залить водой
//hook
additionalAction(); // шаг 4, сделать что-то еще
}
protected void collectSnow() {
System.out.println("собрать снег");
}
abstract protected void formSnow();
protected void fillWithWater() {
System.out.println("залить водой");
}
//hook с пустым телом
protected void additionalAction() {
}
}
Из build() последовательно вызываются все шаги алгоритма, включая пустотелый additionalAction(). В нем снегурочка будет ставиться на постамент.
Классы-наследники
Класс IceSlide (горка); в нем переопределен метод, специфичный для горки:
public class IceSlide extends IceStructure {
@Override
protected void formSnow() {
System.out.println("сформировать горку");
}
}
Класс Snegurochka; в нем переопределены методы, специфичные для снегурочки (включая хук):
public class Snegurochka extends IceStructure {
@Override
protected void formSnow() {
System.out.println("сформировать снегурочку");
}
// переопределяем хук
@Override
protected void additionalAction() {
System.out.println("поставить на постамент");
}
}
Вызов Template Method
Вызывается Template Method так:
public class Main {
public static void main(String[] args) {
IceStructure iceSlide = new IceSlide();
iceSlide.build();
IceStructure snegurochka = new Snegurochka();
snegurochka.build();
}
}
Внутри Template Method последовательно вызываются все шаги алгоритма: как общие, так и отличающиеся от наследника к наследнику. В итоге для горки получим такой результат:
собрать снег сформировать горку залить водой
А для снегурочки такой:
собрать снег сформировать снегурочку залить водой поставить на постамент
Итоги
Благодаря шаблону получился не дублирующийся код.
Вызываем мы метод абстрактного класса, а не подклассов, что тоже хорошо.
Исходный код примера есть на GitHub.