模板设计模式主要来源于生活中有一些事情是有模板可以遵循的。举两个生活中的例子,如泡茶和泡咖啡,看一看。

  泡茶有以下四个步骤:  1, 烧开水;  2 把茶放到水杯中; 3,倒入开水; 4, 加糖。

  泡咖啡也同样有以下四个步骤: 1, 烧开水;  2 把咖啡放到水杯中; 3,倒入开水; 4, 加入糖和牛奶。

  这时,可以清楚地发现,无论是泡茶还是泡咖啡,它们的步骤几乎是相同的:1,开水, 2 放入水杯,3 倒入开水,4 加调味剂。只有具体到泡某种饮料时,它们有些步骤才不同,泡茶肯定是要把茶放到水杯中,而泡咖啡是把咖啡放到水杯中。这时我们就可以把相同的步骤提取出来,生成一个模版,进行共用,而到具体的内容时,它们再有具本的实现。 具体到代码时,模版就可以用抽象类实现,具体的内容可以到它的子类中实现。

  现在用抽象类把模版代码实现一下,

// 抽象基类,为所有的子类提供一个模版
public abstract class Beverage {

    // 具体的模板方法, 要用final关键字进行修饰,避免子类进行修改
    public final void prepareBeverageTemplate() {
        // 1, 烧开水
        boilWater();

        // 2, 放到杯中
        putIntoCup();

        // 加入开水
        addHotWater();

        // 加入调味应有剂
        addCondiments();
    }

    private void boilWater() {
        System.out.println("烧开水");
    }

    protected abstract void putIntoCup();

    private void addHotWater() {
        System.out.println("加水");
    }
    protected abstract void addCondiments();

}

  这里可以看到,在模板中,我们实现了两个方法 boilWater 和 addHotWater,因为这两个方法,对于泡任何饮料来说,都是相同的。另外两个方法则是抽象方法,因为只有到具体泡什么饮料时,这两个方法,才能具体实现,在这里我们并不知道泡茶还是咖啡,因而也就无法确定放入哪种饮料。

  抽象方法的实现要到子类中去, 声明咖啡子类和茶子类实现这两个方法

public class Coffee extends Beverage {

    @Override
    protected void putIntoCup() {
        System.out.println("把咖啡放到水杯中");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }
}
public class Tea extends Beverage {

    @Override
    protected void putIntoCup() {
        System.out.println("把咖啡放到水杯中");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }
}

  现在建立一个测试类Test 来使用一下模版模式

public class Test {

    public static void main(String[] args) {

        // 咖啡制作
        Beverage coffee = new Coffee();
        coffee.prepareBeverageTemplate();  // 调用模版
        System.out.println("\n***********************\n");
        // 茶制作
        Beverage tea = new Tea();
        tea.prepareBeverageTemplate(); // 调用模版
} }

  其实第4个步骤 加调味料不是必须的, 因为有些人喝茶或咖啡是不加调料的,那么怎么让我们程序更加通用化或者更加体现个性化需求?那就要提供一个钩子函数,具体到每个场景,使用不同的钩子函数。这时我们要把 addCondiments 方法放到一个if 函数进行调用, 而if 条件就是我们的钩子函数的调用。

  prepareBeverageTemplate 方法中的代码修改如下

if (isCustomered()) {
    // 加入调味应有剂
    addCondiments();
}
        

  新增 isCustomered 方法

    // 钩子函数,是否需要定置
    protected boolean isCustomered() {

        return true;
    }

  这时只要在子类中override这个钩子函数,就可以实现个性化需求,比如在茶中,复写这个方法

public class Tea extends Beverage {

    @Override
    protected void putIntoCup() {
        System.out.println("把咖啡放到水杯中");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加入糖和牛奶");
    }

    @Override
    protected boolean isCustomered() {
        return false;
    }
}

  这时运行Test, 你就可以去掉加调味料这个步骤

Java 设计模式 ------ 模板设计模式的更多相关文章

  1. Java设计模式——模板设计模式

    模板设计模式 1.模板模式简介 模板模式(Template ):模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑 ...

  2. Java中的模板设计模式,太实用了!

    顾名思义,模板设计模式就是将许多公用的常用的代码封装成一个模板,我们只需要实现不同的业务需求的代码,然后和模板组合在一起,那么就得到完整的逻辑. 在我们的日常开发中,常用的模板模式有两种实现方式:继承 ...

  3. 【设计模式】Java设计模式 - 模板模式

    Java设计模式 - 模板模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  4. JAVA设计模式:模板设计模式

    1.模板设计模式,是为了体现继承的作用.它主要的作用就是在类中定义一些公共的方法和标准,而其具体的实现则叫给其子类来根据子类具体的行为来实现:因为模板设计模式中必经还有一些自己的方法不是抽象的方法,只 ...

  5. java模板设计模式

    1.概述 模板设计模式定义:定义一个操作中的算法骨架,将步骤延迟到子类中. 模板设计模式是一种行为设计模式,一般是准备一个抽象类,将部分逻辑以具体方法或者具体的构造函数实现,然后声明一些抽象方法,这样 ...

  6. Template Method 模板设计模式

    什么是模板设计模式 对于不了解的模板设计模式的来说,可以认为如同古代的造纸术一样,纸所以成型,取决于用了模板的形状,形状又由镂空的木板组成,而你想要造什么纸,又取决于你使用什么材料. 上面提到了两个关 ...

  7. Java进阶篇 设计模式之十四 ----- 总结篇

    前言 本篇是讲述之前学习设计模式的一个总结篇,其目的是为了对这些设计模式的进行一个提炼总结,能够通过查看看此篇就可以理解一些设计模式的核心思想. 设计模式简介 什么是设计模式 设计模式是一套被反复使用 ...

  8. Java进阶篇设计模式之一 ----- 单例模式

    前言 在刚学编程没多久就听说过设计模式的大名,不过由于当时还是个彻彻底底的菜鸟,并没有去触碰.直到在开始工作中对简单的业务代码较为熟悉之后,才正式的接触设计模式.当时最早接触的设计模式是工厂模式,不过 ...

  9. java之模板方法设计模式

    抽象类体现的就是一种模板模式的设计.抽象类作为多个子类的通用模板.子类在抽象类的基础上进行扩张和改造,但子类总体上会保留抽象类的行为方式. 解决的问题: 当功能内部一部分实现是确定的,一部分实现是不确 ...

随机推荐

  1. pip install报错Can't roll back cryptography; was not uninstalled

    当使用pip install或者pip install --upgrade报错 Can't roll back cryptography; was not uninstalled 可以进行以下的尝试: ...

  2. 我的微软最有价值专家(Microsoft MVP)之路

    一.写在前面 2018年对我来说是幸运的一年,对我来说最幸运的事情有两个,一个是在离驾照考试过期还有一个月(报名之后一直没去考)终于拿到了我的驾照,还有一件事莫过于获得了微软MVP.期间,一直有朋友问 ...

  3. FineUIPro v3.6.0 发布了(3 年助力 200 家企业的信息化建设)!

    FineUI(专业版)自从 2014-07-30 发布第一个版本以来,3 年来已经持续更新了 25 个版本,我们的坚持有目共睹,同时也受到了 200 家企业的青睐和信任,感谢一路有你. FineUI( ...

  4. JVM总括三-字节码、字节码指令、JIT编译执行

    JVM总括三-字节码.字节码指令.JIT编译执行 目录:JVM总括:目录 java文件编译后的class文件,java跨平台的中间层,JVM通过对字节码的解释执行(执行模式,还有JIT编译执行,下面讲 ...

  5. C#里面滥用String造成的性能问题

    前两天给我们的json写一个解析函数, 之前用的正宗的json parser, 支持完整的json特性. 但是实际上我们用到特性, 只有key-value的映射, value的类型只有数字和字符串两种 ...

  6. anaconda 出现add 。。。进不去

    找到.condarc 文件  C:\Users\leiyi内 把里面内容替换为 channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pk ...

  7. rest framwork 小试身手

    models.py from django.db import models class Course(models.Model): """ 课程表 "&quo ...

  8. js判断数组是否包含某个字符串变量的实例

    最近碰到一个这样的现象,后台返回的数据中,数组里面有一些有变量值,有一些没有变量值. 举个例子,比如后台返回的例子是这样的: var arr=[ { "status":" ...

  9. Eclipse中修改jsp、html……的编码格式

    一般如果使用的是Eclipse的默认编码格式,在我们保存的时候会提示选择保存的编码格式,保存后英文没有问题,但是中文就会乱码. 修改方式是: Windows——>Preferences——> ...

  10. Linux基础学习笔记4-文本处理

    本章内容 抽取文本的工具 文件内容:less和cat 文件截取:head和tail 按列抽取:cut 按关键字抽取:grep 文件查看 文件查看命令:cat,tac,rev cat [OPTION] ...