Шаблонный метод — это один из 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 way Doing Task1... Doing Task2.1... Doing Task3.1... Doing Task4... Starting the workflow ... the old way Doing 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(); } } |
Это в небольшом смысле лямбда-выражения могут быть использованы в шаблоне шаблона шаблона