Java企业教程系列

使用Java8的Lambda实现模板模式

  模板模式是GoF 23种模式中的一种结构模式,模板模式能够在不改变算法的结构前提1下更改算法的某个具体步骤。

假设这样一个场景,有一个包含4个任务的工作流得按给定的顺序执行,而4个任务可能会在不同的工作流实现系统都需要定制实现。模板方法模式通过封装工作流到一个抽象类,与4个具体任务进行分离,让任务的实现在这个抽象类的子类中完成。

以下面案例:

/**

 * 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...");

  }

}

调用代码:

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();

  }

}

输出结果是:

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 Lambda Expression 和 Default Methods.来优雅实现这个模板模式。我们用Lambda表达式抽象接口来替代抽象类,也就是WorkflowManager2,这个抽象接口只包含一个抽象方法:

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...");

  }

}

注意到我们这里只有一个抽象类doTask2,其他都是default默认方法。

使用Lambda表达式实现模板方法模式如下:

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();

  }

}

方法initiateWorkFlow传入的是WorkflowManager类型,而WorkflowManager是一个doTask2需要实现的函数接口,因此,当我们调用initiateWorkFlow方法时,需要实现这个doTask2,这里实现分别是三个打印输出:()->System.out.println("Doing Task2.1...")

 

Closure Lambda和Monad

使用Java8的Lambda实现Monda

Java 8教程

函数编程