设计模式之模板模式

模板模式

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值