当前位置: 首页 > news >正文

设计模式之模板方法模式的理解

设计模式之模板方法模式的理解

1,模板方法模式(Template Method Pattern)又叫模板模式在一个抽象类公开定义了执行它的方法的模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
2,简单说,模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义算法的某些特定步骤
3,这种类型的设计模式属于行为型模式

实现:
编写抽象类:

public abstract class SoyaMilk {
    //  模板方法 final 不让子类覆盖
    final void make(){
        select();
        addCondiments();
        soak();
        beat();
    }
    void select(){
        System.out.println("第一步:选择好的新鲜黄豆");
    }
    abstract void addCondiments();
    void soak(){
        System.out.println("第三步:黄豆和配料开始浸泡");
    }
    void beat(){
        System.out.println("第四步:黄豆和配料放到豆浆机打碎");
    }

}

实现类1:

public class PeanutSoyaMilk extends SoyaMilk{
    @Override
    void addCondiments() {
        System.out.println("加入上好的花生");
    }
}

实现类2:

public class RedBeanSoyaMilk extends SoyaMilk{
    @Override
    void addCondiments() {
        System.out.println("加入上好的红豆");
    }


}

调用:

public class Client {

    public static void main(String[] args) {

        System.out.println("========制作红豆豆浆=====");
        SoyaMilk red = new RedBeanSoyaMilk();
        red.make();

        System.out.println("========制作花生豆浆=====");
        SoyaMilk peanut = new PeanutSoyaMilk();
        peanut.make();
    }

}

输出:
在这里插入图片描述

模板方法模式之钩子方法

1,在模板方法模式中父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为 ‘钩子’
2,还是用上面做豆浆的列子来讲解,比如,我们还希望制作纯豆浆,不添加任何的配料,请使用钩子方法对前面的方法进行改造

抽象类:

public abstract class SoyaMilk {
    //  模板方法 final 不让子类覆盖
    final void make(){
        select();
        // 加入了钩子方法
        if (customerWantCondiments()){
            addCondiments();
        }
        soak();
        beat();
    }
    void select(){
        System.out.println("第一步:选择好的新鲜黄豆");
    }
    abstract void addCondiments();
    void soak(){
        System.out.println("第三步:黄豆和配料开始浸泡");
    }
    void beat(){
        System.out.println("第四步:黄豆和配料放到豆浆机打碎");
    }
    //钩子方法 决定是否添加配料
    boolean customerWantCondiments(){
        return true;
    }
}

实现类1:

public class PeanutSoyaMilk extends SoyaMilk {
    @Override
    void addCondiments() {
        System.out.println("加入上好的花生");
    }
}

实现类2:

public class PureSoyaMilk extends SoyaMilk{
    @Override
    void addCondiments() {
        // 空实现
    }
    @Override
    boolean customerWantCondiments() {
        return false;
    }
}

实现类3:

public class RedBeanSoyaMilk extends SoyaMilk {
    @Override
    void addCondiments() {
        System.out.println("加入上好的红豆");
    }
}

调用:

public class Client {

    public static void main(String[] args) {

        System.out.println("========制作红豆豆浆=====");
        SoyaMilk red = new RedBeanSoyaMilk();
        red.make();

        System.out.println("========制作花生豆浆=====");
        SoyaMilk peanut = new PeanutSoyaMilk();
        peanut.make();

        System.out.println("========制作纯豆浆=====");
        SoyaMilk cun = new PureSoyaMilk();
        cun.make();
    }

}

输出:
在这里插入图片描述

模板方法的注意事项和细节

1,基本思想是:算法只存于一个地方,也就是在父类中,容易修改,需要修改算法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改,
2,实现了最大代码复用,父类的模板方法和已实现的某些步骤会被子类继承而直接使用
3,即统一了算法,也提供了很大的灵活性,父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现
4,该模式的不足之处:每一个不同实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大
5,一般模板方法都加上final关键字,防止子类重写模板方法
6,模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤,这一系列得步骤基本相同,但其个别步骤在实现时可能不同,通常考虑模板方法模式来处理

相关文章:

  • 小型功率放大器的设计与制作——功率放大器电路总结
  • 接口测试自动化脚本框架5
  • Elasticsearch ik分词器的安装和使用
  • 【Spring Authorization Server 系列】(四)JWS 的签名方式
  • Vue中的循环渲染v-for
  • openresty + prometheus + grafana 搭建。监控网络请求
  • 复盘:统计学派(频率学派)跟贝叶斯学派(贝叶斯公式、朴素贝叶斯)的定义和区别,奥卡姆剃刀和最大似然跟谁更接近
  • Java数据类型与变量
  • od笔试记录
  • Code Review
  • Kubernetes部署服务通过Ingress访问报错413解决
  • 3如何搭建组件库的样式工程之button-scss
  • 飞书第三方ISV服务商应用开发及上架教程
  • JavaScript 运算符和表达式(二)
  • js arr.reduce() reduce方法应用
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Hibernate【inverse和cascade属性】知识要点
  • Intervention/image 图片处理扩展包的安装和使用
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • js中forEach回调同异步问题
  • npx命令介绍
  • PAT A1050
  • Promise初体验
  • React-redux的原理以及使用
  • React组件设计模式(一)
  • 成为一名优秀的Developer的书单
  • 浮现式设计
  • 机器学习 vs. 深度学习
  • 力扣(LeetCode)965
  • 前端代码风格自动化系列(二)之Commitlint
  • 通过git安装npm私有模块
  • 网络应用优化——时延与带宽
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​决定德拉瓦州地区版图的关键历史事件
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • ###C语言程序设计-----C语言学习(6)#
  • ()、[]、{}、(())、[[]]命令替换
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (ZT)一个美国文科博士的YardLife
  • (办公)springboot配置aop处理请求.
  • (二)WCF的Binding模型
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (三)c52学习之旅-点亮LED灯
  • (一)基于IDEA的JAVA基础12
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)nsfocus-绿盟科技笔试题目
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET DataGridView数据绑定说明
  • .net2005怎么读string形的xml,不是xml文件。
  • ::什么意思
  • @Documented注解的作用
  • @JoinTable会自动删除关联表的数据