Шаблонный метод — это один из 23 шаблонов дизайна, описанных в знаменитой книге Эриха Гамма, Ричарда Хелма, Ральфа Джонсона и Джона Влиссидеса « Шаблоны дизайна» . Цель этого шаблона указывается как:
Определите каркас алгоритма в операции, отложив некоторые шаги до подклассов. TemplateMethod позволяет подклассам переопределять определенные этапы алгоритма без изменения структуры алгоритма.
Чтобы объяснить простыми словами, рассмотрим следующий сценарий. Предположим, что существует система рабочих процессов, в которой для успешного завершения рабочего процесса необходимо выполнить 4 задачи в указанном порядке. Некоторые из 4 задач могут быть настроены
реализация различных систем документооборота.
Шаблонный метод может быть применен к описанному выше сценарию путем инкапсуляции системы рабочего процесса в абстрактный класс с несколькими из 4 реализованных задач. И оставьте реализацию оставшихся задач подклассам абстрактного класса.
Итак, вышесказанное при реализации:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/** * Abstract Workflow system */abstract class WorkflowManager2{ public void doTask1(){ System.out.println("Doing Task1..."); } public abstract void doTask2(); public abstract void doTask3(); public void doTask4(){ System.out.println("Doing Task4..."); }}/** * One of the extensions of the abstract workflow system */class WorkflowManager2Impl1 extends WorkflowManager2{ @Override public void doTask2(){ System.out.println("Doing Task2.1..."); } @Override public void doTask3(){ System.out.println("Doing Task3.1..."); }}/** * Other extension of the abstract workflow system */class WorkflowManager2Impl2 extends WorkflowManager2{ @Override public void doTask2(){ System.out.println("Doing Task2.2..."); } @Override public void doTask3(){ System.out.println("Doing Task3.2..."); }} |
Позвольте мне пойти дальше и показать, как используются эти реализации рабочих процессов:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public class TemplateMethodPattern { public static void main(String[] args) { initiateWorkFlow(new WorkflowManager2Impl1()); initiateWorkFlow(new WorkflowManager2Impl2()); } static void initiateWorkFlow(WorkflowManager2 workflowMgr){ System.out.println("Starting the workflow ... the old way"); workflowMgr.doTask1(); workflowMgr.doTask2(); workflowMgr.doTask3(); workflowMgr.doTask4(); }} |
и на выходе будет ..
|
01
02
03
04
05
06
07
08
09
10
|
Starting the workflow ... the old wayDoing Task1...Doing Task2.1...Doing Task3.1...Doing Task4...Starting the workflow ... the old wayDoing Task1...Doing Task2.2...Doing Task3.2...Doing Task4... |
Все идет нормально. Но основная цель этого поста не в том, чтобы создать еще один пост в блоге по шаблонному методу, а в том, чтобы увидеть, как мы можем использовать лямбда-выражения Java 8 и методы по умолчанию . Ранее я уже писал, что в качестве лямбда-выражений могут быть написаны только те интерфейсы, которые имеют один абстрактный метод. В этом примере это означает, что WorkflowManager2 может иметь только одну абстрактную / настраиваемую задачу из 4 задач.
Таким образом, ограничение одним абстрактным методом является основным ограничением и может не применяться во многих сценариях реального времени. Я не хочу повторять те же самые старые примеры шаблонных шаблонных методов, вместо этого мое основное намерение написать это — показать, как можно использовать лямбда-выражения и методы по умолчанию в сценариях, где вы имеете дело с абстрактными классами с помощью одного абстрактного метода.
Если вам интересно, что означают эти лямбда-выражения в java, а также эти методы по умолчанию в java, то, пожалуйста, потратьте некоторое время, чтобы прочитать о лямбда-выражениях и методах по умолчанию, прежде чем продолжить.
Вместо абстрактного класса мы будем использовать интерфейс с методами по умолчанию, поэтому наша система рабочего процесса будет выглядеть так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
interface WorkflowManager{ public default void doTask1(){ System.out.println("Doing Task1..."); } public void doTask2(); public default void doTask3(){ System.out.println("Doing Task3..."); } public default void doTask4(){ System.out.println("Doing Task4..."); }} |
Теперь, когда у нас есть система рабочих процессов с настраиваемой задачей 2, мы продолжим и инициируем некоторые настроенные рабочие процессы, используя лямбда-выражения
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
public class TemplateMethodPatternLambda { public static void main(String[] args) { /** * Using lambda expression to create different * implementation of the abstract workflow */ initiateWorkFlow(()->System.out.println("Doing Task2.1...")); initiateWorkFlow(()->System.out.println("Doing Task2.2...")); initiateWorkFlow(()->System.out.println("Doing Task2.3...")); } static void initiateWorkFlow(WorkflowManager workflowMgr){ System.out.println("Starting the workflow ..."); workflowMgr.doTask1(); workflowMgr.doTask2(); workflowMgr.doTask3(); workflowMgr.doTask4(); }} |
Это в небольшом смысле лямбда-выражения могут быть использованы в шаблоне шаблона шаблона