Статьи

Шаблонный метод Шаблон Учебник с примерами Java

Сегодняшний шаблон — это шаблонный метод, который определяет заглушку для алгоритма, откладывая некоторые этапы реализации до подклассов.

Шаблон в реальном мире 

Шаблон Template Method используется, когда существуют две или более реализации аналогичного алгоритма. В реальном мире шаблоны используются постоянно: для архитектурных планов и во всей области проектирования. Может быть определен шаблонный план, который затем строится с дальнейшими изменениями. Например, базовый план дома может иметь много вариантов, таких как добавление расширений или использование другой системы отопления.

Refcard Designs Patterns
Для лучшего обзора самых популярных шаблонов дизайна, лучше всего начать с Refcard Designs Patterns от DZone

Шаблон шаблона

Шаблон Template Method известен как поведенческий шаблон, так как он используется для управления алгоритмами, отношениями и обязанностями между объектами. Определение метода шаблона, представленное в оригинальной книге «Банды четырех» на DesignPatterns, гласит: 

Определяет каркас алгоритма в методе, откладывая некоторые шаги до подклассов. Шаблонный метод позволяет подклассам переопределять определенные этапы алгоритма без изменения структуры алгоритмов.

На практике шаблон Template Method довольно прост — давайте посмотрим на представление диаграммы классов

AbstractClass содержит templateMethod () , который должен быть сделан окончательным , так что он не может быть переопределен. Этот метод шаблона использует другие операции, доступные для запуска алгоритма, но он не связан для фактической реализации этих методов. Все операции, используемые этим методом шаблона, делаются абстрактными, поэтому их реализация откладывается до подклассов.

В ConcreteClass реализует все операции , требуемые templateMethod , которые были определены в качестве абстрактного в родительском классе. Может быть много разных ConcreteClasses. 

Шаблонный метод использует принцип Голливуда: не звоните нам, мы вам позвоним. Метод шаблона в родительском классе контролирует весь процесс, при необходимости «вызывая» методы подкласса. Голливудский принцип избегает низкоуровневых компонентов, зависящих от высокоуровневых компонентов, и вместо этого дает этим низкоуровневым классам (ConcreteClass) способ подключения к родительскому классу (AbstractClass). 

В разбивке существует четыре различных типа методов, используемых в родительском классе: 

  • Конкретные методы Стандартные полные методы, которые полезны для подклассов. Эти методы обычно являются практическими методами.
  • Абстрактные методы Методы, не содержащие реализации, которые должны быть реализованы в подклассах.
  • Методы хука Методы, содержащие реализацию по умолчанию, которая может быть переопределена в некоторых классах. Методы хука предназначены для переопределения, а конкретные методы — нет.
  • Шаблонные методы Метод, который вызывает любой из методов, перечисленных выше, для описания алгоритма без необходимости реализации деталей.

Когда я буду использовать этот шаблон?

Шаблон Template Method используется, когда 

  • Когда поведение алгоритма может меняться, вы позволяете подклассам реализовать поведение через переопределение
  • Вы хотите избежать дублирования кода, реализуя варианты алгоритма в подклассах
  • Вы хотите контролировать точку, в которой разрешено создание подклассов.

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

Как вы можете себе представить, использование Template Template довольно распространено. Вы найдете, что он используется в классе Arrays и использует его для сортировки. JFrame использует update () в качестве метода шаблона, подклассы JFrame используют paint (Graphics g) в качестве метода подключения.

Так как это работает в Java?

Для нашего примера Java, мы будем использовать кросс-компилятор в качестве примера. Сначала мы создадим базовый базовый класс кросс-компилятора с его методом crossCompile (), который является связующим звеном для выполнения всего алгоритма.

public abstract class CrossCompiler {
  public final void crossCompile() {
    collectSource();
    compileToTarget();
  }
  //Template methods
  protected abstract void collectSource();
  protected abstract void compileToTarget();
}

Далее мы создадим две конкретные реализации нашего кросс-компилятора для iPhone и для Android: 

 

public class IPhoneCompiler extends CrossCompiler {
  protected void collectSource() {
    //anything specific to this class
  }
  protected void compileToTarget() {
    //iphone specific compilation
  }
}
public class AndroidCompiler extends CrossCompiler {
  protected void collectSource() {
    //anything specific to this class
  }
  protected void compileToTarget() {
    //android specific compilation
  }
}

Чтобы завершить этот пример, вот как вы должны использовать свои кросс-компиляторы

public class Client {
  public static void main(String[] args) {
    CrossCompiler iphone = new IPhoneCompiler();
    iphone.crossCompile();
    CrossCompiler android = new AndroidCompiler();
    android.crossCompile();
  }
}

Остерегайтесь недостатков

Есть некоторые недостатки шаблона шаблона. Во-первых, ваши базовые классы имеют тенденцию загромождаться большим количеством, казалось бы, не связанного кода. За ходом программы немного сложнее следить — без помощи пошагового выполнения кода с помощью отладчика. Алекс Миллер подробно излагает причины, по которым он ненавидит шаблонный метод в своем блоге. 

Следующий

Мы рассмотрим шаблон Prototype позже на этой неделе.

Наслаждайтесь всей серией «Design Patterns Uncovered»:

Образцы творчества

Структурные паттерны

Поведенческие образцы