閱讀119 返回首頁    go 阿裏雲 go 技術社區[雲棲]


采用Java 8中Lambda表達式和默認方法的模板方法模式

模板方法模式是“四人幫”(譯者注:Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides)所著《Design Patterns book》一書中所描述的23種設計模式其中的一種,該模式旨在:

“Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.

TemplateMethod lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure”。

即模板方法定義一個算法的架構,並將某些步驟推遲到子類中實現。模板方法允許子類在不改變算法架構的情況下,重新定義算法中某些步驟。

為了以更簡單的術語描述模板方法,考慮這個場景:假設在一個工作流係統中,為了完成任務,有4個任務必須以給定的執行順序執行。在這4個任務中,不同工作流係統的實現可以根據自身情況自定義任務的執行內容。

模板方法可以應用在上述場景中:將工作流係統的4個核心任務封裝到抽象類當中,如果任務可以被自定義,則將可自定義的任務推遲到子類中實現。

代碼實現:

01 /** 
02  * Abstract Workflow system 
03  */
04 abstract class WorkflowManager2{
05  
06     public void doTask1(){
07  
08         System.out.println("Doing Task1...");
09  
10     }
11  
12     public abstract void doTask2();
13  
14     public abstract void doTask3();
15  
16     public void doTask4(){
17  
18         System.out.println("Doing Task4...");
19  
20     }
21  
22 }
23  
24 /** 
25  * One of the extensions of the abstract workflow system 
26  */
27 class WorkflowManager2Impl1 extends WorkflowManager2{
28  
29     @Override
30     public void doTask2(){
31  
32         System.out.println("Doing Task2.1...");
33  
34     }
35  
36     @Override
37     public void doTask3(){
38  
39         System.out.println("Doing Task3.1...");
40  
41     }
42  
43 }
44  
45 /** 
46  * Other extension of the abstract workflow system 
47  */
48 class WorkflowManager2Impl2 extends WorkflowManager2{
49  
50     @Override
51     public void doTask2(){
52  
53         System.out.println("Doing Task2.2...");
54  
55     }
56  
57     @Override
58     public void doTask3(){
59  
60         System.out.println("Doing Task3.2...");
61  
62     }
63  
64 }

我們來看看工作流係統如何使用:

01 public class TemplateMethodPattern {
02  
03     public static void main(String[] args) {
04  
05         initiateWorkFlow(new WorkflowManager2Impl1());
06  
07         initiateWorkFlow(new WorkflowManager2Impl2());
08  
09     }
10  
11     static void initiateWorkFlow(WorkflowManager2 workflowMgr){
12  
13         System.out.println("Starting the workflow ... the old way");
14  
15         workflowMgr.doTask1();
16  
17         workflowMgr.doTask2();
18  
19         workflowMgr.doTask3();
20  
21         workflowMgr.doTask4();
22  
23     }
24  
25 }

輸出如下所示:

01 Starting the workflow ... the old way
02  
03 Doing Task1...
04  
05 Doing Task2.1...
06  
07 Doing Task3.1...
08  
09 Doing Task4...
10  
11 Starting the workflow ... the old way
12  
13 Doing Task1...
14  
15 Doing Task2.2...
16  
17 Doing Task3.2...
18  
19 Doing Task4...

目前為止一切順利。但是本篇博客的主要關注點不是模板方法模式,而是如何利用Java 8的Lambda表達式和默認方法實現模板方法模式。我之前已經說過,接口隻有在隻聲明了一個抽象方法的前提下,才可以使用Lambda表達式。這個規則在本篇的例子中應這樣解釋:WorkflowManager2隻能有一個抽象或者說自定義的任務。

如果你仍然對Java 8中的Lambda表達式和默認方法感到疑惑,可以在深入研究之前,花一點時間看一看Lambda表達式默認方法這兩篇文章。

我們可以利用帶有默認方法的接口替代抽象類,所以我們的新工作流係統如下所示:

01 interface WorkflowManager{
02  
03     public default void doTask1(){
04  
05         System.out.println("Doing Task1...");
06  
07     }
08  
09     public void doTask2();
10  
11     public default void doTask3(){
12  
13         System.out.println("Doing Task3...");
14  
15     }
16  
17     public default void doTask4(){
18  
19         System.out.println("Doing Task4...");
20  
21     }
22  
23 }

現在我們的工作流係統帶有一個可自定義的任務2,我們繼續往下走,利用Lambda表達式處理初始化工作:

01 public class TemplateMethodPatternLambda {
02  
03     public static void main(String[] args) {
04  
05        /**     
06         * Using lambda expression to create different      
07         * implementation of the abstract workflow 
08         */
09         initiateWorkFlow(()->System.out.println("Doing Task2.1..."));
10  
11         initiateWorkFlow(()->System.out.println("Doing Task2.2..."));
12  
13         initiateWorkFlow(()->System.out.println("Doing Task2.3..."));
14  
15     }
16  
17     static void initiateWorkFlow(WorkflowManager workflowMgr){
18  
19         System.out.println("Starting the workflow ...");
20  
21         workflowMgr.doTask1();
22  
23         workflowMgr.doTask2();
24  
25         workflowMgr.doTask3();
26  
27         workflowMgr.doTask4();
28  
29     }
30  
31 }

這就是一個Lambda表達式應用在模板方法模式中的例子。

最後更新:2017-05-23 09:31:43

  上一篇:go  嵌入Groovy
  下一篇:go  線程安全及不可變性