文章目录

  • 模板模式
    • 解决的问题
    • 结构
    • 实例
    • 存在的问题
    • 适用场景
  • JDK源码 - InputStream

行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式:

  • 类行为模式:采用继承机制来在类间分派行为

  • 对象行为模式:采用组合或聚合在对象间分配行为

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型模式分为:

  • 模板方法模式
  • 策略模式
  • 命令模式
  • 职责链模式
  • 状态模式
  • 观察者模式
  • 中介者模式
  • 迭代器模式
  • 访问者模式
  • 备忘录模式
  • 解释器模式

以上 11 种行为型模式,除了模板方法模式解释器模式是类行为型模式,其他的全部属于对象行为型模式。

模板模式

**模板方法模式:**定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

  • 其核心是将一些行为延迟到子类中进行实现

解决的问题

在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。

例如,去银行办理业务一般要经过以下 4 个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现

结构

抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

  • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

  • 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

    • 抽象方法 (Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

      • 具体方法 (Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

      • 钩子方法 (Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

        • 一般钩子方法是用于判断的逻辑方法,这类方法名一般为 isXxx,返回值类型为 boolean 类型。

具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

实例

炒菜

炒菜的步骤是固定的,分为【倒油】、【热油】、【倒蔬菜】、【倒调料品】、【翻炒】等步骤。

现通过模板方法模式来用代码模拟,类图如下:

抽象类:定义模板方法和抽象方法。

为防止恶意操作,一般模板方法都加上 final 关键词。

public abstract class AbstractClass {// 模板方法定义public final void cookProcess() {pourOil();heatOil();pourVegetable();pourSauce();fry();}// 第一步:倒油是一样的,直接实现public void pourOil() {System.out.println("倒油");}// 第二步:热油是一样的,直接实现public void heatOil() {System.out.println("热油");}// 第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心),抽象方法public abstract void pourVegetable();// 第四步:倒调味料是不一样,抽象方法public abstract void pourSauce();// 第五步:翻炒是一样的,直接实现public void fry() {System.out.println("炒啊炒啊炒到熟啊");}
}
  • 倒蔬菜和倒调味料在子类实现,但是我们的模板方法调用了对应的方法,因为子类进行实现,所以调用的是子类实现的方法——反向控制

具体子类:实现模板方法中的抽象方法和钩子方法

public class ConcreteClass_BaoCai extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是包菜");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是辣椒");}
}
public class ConcreteClass_CaiXin  extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是菜心");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是蒜蓉");}
}

测试类

public class Client {public static void main(String[] args) {// 炒包菜// 创建对象ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();// 调用炒菜的功能baoCai.cookProcess();}
}
//倒油
//热油
//下锅的蔬菜是包菜
//下锅的酱料是辣椒
//炒啊炒啊炒到熟啊

存在的问题

优点:

  • 提高代码复用性:将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制:通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,符合“开闭原则”。

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

适用场景

  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

JDK源码 - InputStream

InputStream 类中使用了模板方法模式。在 InputStream 类中定义了多个 read() 方法,如下:

public abstract class InputStream implements Closeable {// 抽象方法,要求子类必须重写public abstract int read() throws IOException;public int read(byte b[]) throws IOException {return read(b, 0, b.length);}public int read(byte b[], int off, int len) throws IOException {if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();} else if (len == 0) {return 0;}int c = read(); // 调用了无参的read方法,该方法是每次读取一个字节数据//因为该类中是抽象方法,所以调用的方法具体实现是子类进行实现if (c == -1) {return -1;}b[off] = (byte)c;int i = 1;try {for (; i < len ; i++) {c = read(); // 调用了无参的read方法,该方法是每次读取一个字节数据if (c == -1) {break;}b[off + i] = (byte)c;}} catch (IOException ee) {}return i;}
}

从上面代码可以看到,无参的 read() 方法是抽象方法,要求子类必须实现。而 read(byte b[]) 方法调用了 read(byte b[], int off, int len) 方法,所以在此处重点看的方法是带三个参数的方法。

在该方法中,可以看到调用了无参的抽象的 read() 方法。

总结如下:在 InputStream 父类中已经定义好了读取一个字节数组数据的方法是每次读取一个字节,并将其存储到数组的第一个索引位置,读取 len 个字节数据。具体如何读取一个字节数据呢?由子类实现。

第十三章行为型模式—模板模式相关推荐

  1. 设计模式之策略模式+工厂模式+模板模式结合

    设计模式之策略模式+模板模式 为什么总是学不好设计模式 从"登录功能"中发现问题. 首先我们简单的了解功能需求: 于是你开始干活了: 1.控制层代码如下,根据不同的登录方式调用不同 ...

  2. Java设计模式之策略模式+工厂模式+模板模式

    Java设计模式之策略模式+工厂模式+模板模式 1.策略模式+工厂模式+模板模式 个人的理解:实际开发工程中,一些业务很复杂的逻辑使用很多的 if 或者 if···else 语句,不利于维护和扩展,为 ...

  3. 设计模式-05.01-行为型-观察者模板模式

    文章目录 观察者模式[常用] Demo案例-天气预报 方案一 WeatherData CurrentConditions Client 问题分析 观察者模式方案 Subject[接口] Observe ...

  4. 【设计模式】【行为型】模板模式之模拟去商场购物

    一.概念 1.1 概念 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计 ...

  5. 【设计模式系列】行为型之模板模式

    目录 理论 实践 总结 理论 1.模板模式:定义一个操作算法中的框架,而将这些步骤延迟加载到子类中. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤: 2.角色: 抽象模板 ...

  6. 行为模式(模板模式命令模式备忘录模式)

    目录 模板方法模式(Template) 介绍 实现 命令模式(Command) 介绍 实现 备忘录模式(Memento) 介绍 实现 模板方法模式(Template) 一个抽象类公开定义了执行它的方法 ...

  7. 模板方法模式(模板模式)——钩子方法

    豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材->添加配料->浸泡->放到豆浆机打碎 通过添加不同的配料,可以制作出不同口味的豆浆 选材.浸泡和放到豆浆机打碎这几个 ...

  8. 常用设计模式-策略模式+工厂模式+模板模式(使用场景、解决方案)

    在策略模式+工厂模式中,没有使用到模板模式,因为张三和李四的业务逻辑都是调用AAA方法,如果现在在增加一个方法,次方法只需要李四一人去实现BBB方法,此时张三的handel中就会报错,需要张三也去实现 ...

  9. 记录策略模式模板模式的一次应用过程

    目录 1.业务背景 2.代码示例 3.总结 1.业务背景 我们的一套H5应用程序前.后端只有一套部署,但是domain确有Fenqile.JiaoYiMao.Mp.ThunderMP.Thunder. ...

最新文章

  1. C#把TextBox.Text的几万条数据按数据格式导出Excel报错:Insufficient memory to continue the execution of the program.
  2. [FI] SAP 关于标准成本、计划成本、目标成本、实际成本
  3. 两个date 相差得到月份_DATE和TIME函数的正确打开方式
  4. byte数组转字符串_leetcode刷题844比较含退格的字符串(带代码解析,带知识点回顾)...
  5. Redis在生产中不得不重视的几个运维问题
  6. ivx中字体显示_iVX云服务费用优化 · 上篇
  7. 如何优化 App 的启动耗时?
  8. 学习Node.js并开始在浏览器之外执行JavaScript
  9. mybatis中association和collection的column传入多个参数值
  10. 手机号判断正则php2019,2019手机号码JS正则表达式验证实例代码
  11. layui引入jQuery
  12. Ansbile实战经验
  13. MyBatis官方文档——XML映射文件部分
  14. VC2013生成的程序兼容WindowsXP操作系统
  15. TPP:你的数据你做主 TPP将撤销政府的数据主权
  16. java案例:模拟双色球中奖
  17. 【NOIP2017普及组】跳房子
  18. 第三章 java集合
  19. python网络编程好学吗_年薪30万+的python编程难不难?好学吗?
  20. Postman + Pre-resuestScript:预请求脚本发送POST请求

热门文章

  1. (更新)数据挖掘,自学一年拿了腾讯京东华为网易YY的Offer,方法与建议
  2. 2W字剖析数据治理平台建设经验(建议收藏)
  3. delphi xe3 mysql,Mysql ZeosLib Delphi XE3
  4. UltraEdit调整一行显示的十六进制的字符个数
  5. 阿里云高级专家朱小平:如何打造应对超大流量的负载均衡
  6. 如何将应用程序在Iphone真机上调试
  7. python你想知道的都在这里 python资源大全中文版
  8. 淘宝滑块的解决方法和接口
  9. absible-role
  10. mysql和oracle课程,Oracle MySQL 管理实战应用培训