欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式之模板模式

程序员文章站 2022-06-13 13:47:50
...

模板模式

1.需求:如何制作豆浆?

  • 制作豆浆的流程: 选材 -> 添加配料 -> 浸泡 -> 放到豆浆机里打碎
  • 制作豆浆的逻辑大体相同,在添加配料的时候可以选择添加不同的配料制作不同的豆浆(红豆豆浆,花生豆浆)
  • 解决方法: 使用模板模式模拟制作豆浆的过程

2.模板模式介绍

  1. 模板模式(Template Pattern)又称为模板方法模式(Template Method Pattern),在一个抽象类中公开定义了执行逻辑,它的子类可以去重写该方法,定制该逻辑

  2. 模板模式就像是一个骨架,定义一个抽象的执行结构

  3. 模板模式中的角色:

    • .AbstractClass: 抽象类,内部有一个模板方法(template),规定了算法大致的流程(算法骨架)
    • ConcreteClass: 子类,内部重新实现抽象方法。不一样的子类可以实现不一样的方法
  4. 什么是钩子方法:

    • 在模板模式的抽象类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况是否需要覆盖该方法
    • 假设我们现在需要追加需求:**如何制作纯豆浆?**如何修改代码? => 在设计添加逻辑时,设置一个钩子函数判断该方法是否执行。
  5. 模板模式的结构图:设计模式之模板模式

3.代码演示

  • uml

设计模式之模板模式

  • 代码一览
package com.liz.GOF23.template_method;

//抽象类,表示豆浆
public abstract class SoyaMilk {
    //模板方法,不让子类覆盖
    final void make() {
        //流程一览
        select();
        //此处是为了制作纯豆浆,设计的逻辑
        if(isAdd()){
            add();
        }
        soak();
        beat();
    }

    //选材
    void select() {
        System.out.println("第一步:选择材料");
    }

    //添加配料(配料可能不同)

    public abstract void add();

    //浸泡
    void soak() {
        System.out.println("第三步:浸泡");
    }

    //打磨
    void beat() {
        System.out.println("第四步:打磨");
    }

    //钩子方法,判断是否需要添加配料(如何在子类中重写为false 则默认不执行add方法 [见make逻辑])
    boolean isAdd(){
        return true;
    }

}


//实现类1
package com.liz.GOF23.template_method;
//红豆豆浆
public class RedBeanSoyaMilk extends SoyaMilk {
    @Override
    public void add() {
        System.out.println("第三步:加入红豆");
    }
}

//实现类2
public class PeanutSoyaMilk extends SoyaMilk {
    @Override
    public void add() {
        System.out.println("第三步:加入花生");
    }
}
//实现类2
public class PureSoyaMilk extends SoyaMilk {
    @Override
    public void add() {
        //空实现
    }
    //此时不会去调用add方法
    @Override
    boolean isAdd() {
        return false;
    }
}
//调用者
    public static void main(String[] args) {
        SoyaMilk red = new RedBeanSoyaMilk();
        SoyaMilk peanut = new PeanutSoyaMilk();
        //调用模板方法
        red.make();
        System.out.println("-----------------------");
        peanut.make();
        System.out.println("-----------------------");
        //实现钩子方法 调用纯豆浆
        SoyaMilk pure = new PureSoyaMilk();
        pure.make();
    }
}
  • 执行结果:
    设计模式之模板模式

4.模板模式细节

  1. 一般在模板方法上加上final关键字,防止子类重写模板方法(见上述抽象类中的make方法)

  2. 模板方法的优缺点

    • 优点:
      • 封装不变的部分,修改可变的部分
      • 提取公共的代码,便于维护
      • 行为由父类控制,子类控制(符合开闭原则)
      • 代码复用性高,降低代码的冗余度
    1. 缺点:
      1. 每一种不同的实现都要加上一个子类
      2. 由于继承的关系,父类增加或者修改方法的时候,子类都需要实现
  3. 模板模式的适用环境:当完成某个过程时,该过程需要执行一系列步骤(一系列步骤基本相同),但是个别步骤在实现的时候可能细节不同的时候,可以使用模板模式(+钩子函数)来处理。

参考资料:
韩顺平:java设计模式
https://www.jianshu.com/p/c3a5b653b0d3

相关标签: 设计模式