Реализация шаблона шаблона шаблона в Java
1. обзор
В этом кратком руководстве мы увидим, как использоватьtemplate method pattern - один из самых популярных паттерновGoF.
Это упрощает реализацию сложных алгоритмов за счет инкапсуляции логики в один метод.
2. Реализация
Чтобы продемонстрировать, как работает шаблон метода шаблона, давайте создадим простой пример, который представляет собой создание компьютерной станции.
Учитывая определение шаблона,the algorithm’s structure will be defined in a base class that defines the template build() method:
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();
// ...
}
The ComputerBuilder class is responsible for outlining the steps required to build a computer by declaring methods for adding and setting up different components, например материнская плата и процессор.
Здесьthe build() method is the template method, который определяет шаги алгоритма сборки компонентов компьютера и возвращает полностью инициализированные экземплярыComputer.
Обратите внимание, что it’s declared as final to prevent it from being overridden.
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");
}
}
А вот вариантHighEndComputerBuilder:
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.AbstractSet..
Например,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.
Шаблонный шаблонный метод способствует повторному использованию и развязке кода, но за счет использования наследования.
Как всегда, доступны все примеры кода, показанные в этой статьеover on GitHub.