1. Обзор
В этом кратком руководстве мы увидим, как использовать шаблон метода template – один из самых популярных шаблонов GoF .
Это облегчает реализацию сложных алгоритмов, инкапсулируя логику в одном методе.
2. Реализация
Чтобы продемонстрировать, как работает шаблон метода шаблона, давайте создадим простой пример, который представляет собой построение компьютерной станции.
Учитывая определение шаблона, структура алгоритма будет определена в базовом классе, который определяет шаблон build() метод :
public abstract class ComputerBuilder { // ... public final Computer buildComputer() { addMotherboard(); setupMotherboard(); addProcessor(); return new Computer(computerParts); } public abstract void addMotherboard(); public abstract void setupMotherboard(); public abstract void addProcessor(); // ... }
Класс Computer Builder отвечает за описание шагов , необходимых для создания компьютера, путем объявления методов добавления и настройки различных компонентов , таких как материнская плата и процессор.
Здесь метод build() является шаблонным методом , который определяет этапы алгоритма сборки деталей компьютера и возвращает полностью инициализированные экземпляры Computer .
Обратите внимание, что i t объявлен как final , чтобы предотвратить его переопределение.
3. В действии
Поскольку базовый класс уже установлен, давайте попробуем использовать его, создав два подкласса. Один из них строит “стандартный” компьютер, а другой-“высококлассный” компьютер:
public class StandardComputerBuilder extends ComputerBuilder { @Override public void addMotherboard() { computerParts.put("Motherboard", "Standard Motherboard"); } @Override public void setupMotherboard() { motherboardSetupStatus.add( "Screwing the standard motherboard to the case."); motherboardSetupStatus.add( "Pluging in the power supply connectors."); motherboardSetupStatus.forEach( step -> System.out.println(step)); } @Override public void addProcessor() { computerParts.put("Processor", "Standard Processor"); } }
А вот вариант High End Computer Builder :
public class HighEndComputerBuilder extends ComputerBuilder { @Override public void addMotherboard() { computerParts.put("Motherboard", "High-end Motherboard"); } @Override public void setupMotherboard() { motherboardSetupStatus.add( "Screwing the high-end motherboard to the case."); motherboardSetupStatus.add( "Pluging in the power supply connectors."); motherboardSetupStatus.forEach( step -> System.out.println(step)); } @Override public void addProcessor() { computerParts.put("Processor", "High-end Processor"); } }
Как мы видим, нам не нужно было беспокоиться обо всем процессе сборки, а только о предоставлении реализаций для отдельных методов.
А теперь давайте посмотрим на это в действии:
new StandardComputerBuilder() .buildComputer(); .getComputerParts() .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v)); new HighEndComputerBuilder() .buildComputer(); .getComputerParts() .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));
4. Методы шаблонов в библиотеках ядра Java
Этот шаблон широко используется в библиотеках ядра Java, например, с помощью java.util.AbstractList или java.util.Абстрактный набор.
Например, Abstract List предоставляет скелетную реализацию интерфейса |/List .
Примером метода шаблона может быть метод addAll () , хотя он явно не определен как final:
public boolean addAll(int index, Collection extends E> c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; }
Пользователям нужно только реализовать метод add() :
public void add(int index, E element) { throw new UnsupportedOperationException(); }
Здесь программист несет ответственность за предоставление реализации для добавления элемента в список по заданному индексу (вариантная часть алгоритма листинга).
5. Заключение
В этой статье мы показали шаблон метода шаблона и то, как его реализовать в Java.
Шаблон метода шаблона способствует повторному использованию кода и развязке, но за счет использования наследования.
Как всегда, все примеры кода, показанные в этой статье, доступны на GitHub .