采用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表达式应用在模板方法模式中的例子。

相关文章
|
1天前
|
Java
探索Java世界的奇妙工具——运算符与表达式运算符
探索Java世界的奇妙工具——运算符与表达式运算符
5 0
|
1天前
|
Java
【JAVA进阶篇教学】第二篇:JDK8中Lambda表达式
【JAVA进阶篇教学】第二篇:JDK8中Lambda表达式
|
1天前
|
XML JavaScript Java
详解Java解析XML的四种方法
详解Java解析XML的四种方法
|
2天前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
2天前
|
Java C语言
详解java方法与递归
详解java方法与递归
9 3
|
2天前
|
SQL Java 数据库连接
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
JDBC Java标准库提供的一些api(类+方法) 统一各种数据库提供的api
9 0
|
Java Unix 数据库管理
java定时框架:表达式设置
Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知)   时间格式: ,   分别对应: 秒>分>小时>日>月>周>年,  举例: 1.
846 0
|
2天前
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
10 1
|
1天前
|
安全 Java
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
|
1天前
|
安全 Java
【JAVA进阶篇教学】第六篇:Java线程中状态
【JAVA进阶篇教学】第六篇:Java线程中状态