模板方法模式简介

模板方法(Template method),顾名思义,就是做一些任务的通用流程。如网上有许多自我介绍模板、推荐信模板,即开头和结尾可能都是差不多的内容,而中间需要客户去修改一下即可使用。设计模式源自生活,模板方法就在类似的场景下诞生了。模板方法是指写一个操作中的算法框架,而将一些步骤延迟到子类中去实现,这样就使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法的设计方法

模板方法通常会设计一个抽象类,内部定义一些需要子类去实现的抽象方法,因为这些方法可能因不同的子类会有不同的实现,因此定义为抽象方法。另外,抽象类中应该有一个或多个模板方法,即固定好的框架,而且这个方法的修饰符通常定义为final,这样做是为了防止子类去覆写这个模板,因为我们认为模板是固定的,不容修改。而在这个固定的模板方法内部,会调用那些抽象方法,来一步一步实现整个算法的流程。通常,子类要去继承这个抽象父类,并根据自己的业务逻辑实现里面的抽象方法。

模板方法的特点

模板方法清晰地划定了某一类业务的变与不变,为一类业务做好了流程框架,为子类提供了公共的代码,并且子类的行为完全由父类来控制,实现了代码的可维护性和可扩展性。父类不容修改,子类可以去扩展,很好地符合了设计模式的开闭原则——对修改封闭,对扩展开放。

注意模板方法设计模式与抽象类设计的区别,抽象类这种设计模式是父类定义一些抽象方法,让子类去实现,因此子类通常有更多的自由空间;而模板方法中是父类定义好了算法框架,子类去实现父类其中的抽象方法,因此子类的作用可以影响父类。

模板方法的应用示例

背景介绍

假设现在要制作一些饮料产品,比方说要泡茶和咖啡。泡茶和泡咖啡的流程大体上可以分为四步,第一将水煮沸,第二烘焙原料,第三倒入杯中,第四加入调料。通常第一步和第三步动作是一样的,所以我们可以在父类中将方法直接写好,而第二步和第四步则随着泡茶还是泡咖啡有所不同,因此我们设计为抽象方法,让子类去实现。而这四步整体上又是泡饮料的固定流程,所以我们将这四步封装在一个方法中,并且设置这个方法的修饰符为final,以防子类去修改它。

模板方法

下面先写出模板方法的代码:

package com.template;

/**

* 模板模式

* 抽象基类,为所有子类提供算法框架

* 业务:提神饮料

* @author zzw

*

*/

public abstract class RefreshBeverage {

/*

* 制备饮料的模板方法,指定算法框架

*/

//阻止子类对模板方法进行复写

public final void prepareBeverageTemplate() {

//步骤1:将水煮沸

boilWater();

//步骤2:炮制饮料

brew();

//步骤3:倒入杯中

pourInCup();

//步骤4:加入调料(引入钩子函数,从用户角度出发,可选择性)

if(isCustomerWantCondiments()) {

addCondiments();

}

}

/*

* Hook,钩子函数

* 提供一个默认或空的实现

* 具体子类可以自行决定是否挂钩以及如何挂钩

* 询问用户是否加入调料

*/

protected boolean isCustomerWantCondiments() {

// 默认设置

return true;

}

//抽象方法,由子类实现

protected abstract void addCondiments();

private void pourInCup() {

// 倒入杯中

System.out.println("倒入杯中");

}

//抽象方法,由子类实现

protected abstract void brew();

private void boilWater() {

// 将水煮沸

System.out.println("将水煮沸");

}

}

子类实现

由于泡茶喝泡咖啡的具体实现有所不同,并且还可以使用钩子函数来判断用户是否需要加调料,这样使得流程更具人性化。

泡茶:

package com.template;

/**

* 茶叶制备的具体实现

* 子类

* @author zzw

*

*/

public class TeaBeverage extends RefreshBeverage {

@Override

protected void addCondiments() {

// TODO Auto-generated method stub

System.out.println("加入茶叶调料");

}

@Override

protected void brew() {

// TODO Auto-generated method stub

System.out.println("烘焙茶叶");

}

}

泡咖啡:

package com.template;

public class CoffeeBeverage extends RefreshBeverage {

@Override

protected void addCondiments() {

// TODO Auto-generated method stub

System.out.println("加入咖啡调料");

}

@Override

protected void brew() {

// TODO Auto-generated method stub

System.out.println("烘焙咖啡");

}

}

由于中国茶一般不加调料,所以这里如果引入一个中国茶的话,在继承茶的基础上,将是否加调料设为不加即可。

package com.template;

/**

* 制备中式茶

* 不需要加调料

* 因此选择挂钩函数

* 其他的则继承茶的制作

* @author Administrator

*

*/

public class ChineseTeaBeverage extends TeaBeverage {

@Override

protected boolean isCustomerWantCondiments() {

// TODO Auto-generated method stub

return false;

}

}

钩子函数

钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

对每种类型的钩子由系统来维护一个钩子链,最近安装的钩子放在链的开始,而最先安装的钩子放在最后,也就是后加入的先获得控制权。如本博文中提到的是否加入调料即为一种钩子函数,它对是否加调料具有决定权。

如果指定确定的线程,即为线程专用钩子;如果指定为空,即为全局钩子。其中,全局钩子函数必须包含在DLL(动态链接库)中,而线程专用钩子还可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。

模板方法模式的使用场景

模板方法可以用于一次性实现一个算法的不变的部分,并将可变的部分留给子类去实现;子类的公共代码部分应该被提炼到父类中去写好,防止代码重复编写;控制子类的扩展,模板方法只允许在特定点调用钩子函数,这样就只允许在这些点进行扩展。

java模板方法模式_Java设计模式之模板方法模式相关推荐

  1. java解耦的模板模式_Java 设计模式(9) —— 模板模式

    一.模板模式 封装了一个算法步骤,并允许子类为一个或多个步骤方法提供实现.模板模式可以使子类在不改变算法结构的情况下,重新定义算法中的某些步骤. 模板模式 二.示例 泡咖啡与泡茶: 泡咖啡的步骤: 水 ...

  2. java web简单工厂模式_JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

    在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一 ...

  3. Java创新型模式_java设计模式--创建型模式(一)

    2016-04-24 10:10:34 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂 ...

  4. 格力电器Java面试题_JAVA设计模式学习--工厂模式

    今天谈一下对工厂模式学习的总结. 看完视频和文章之后要自己表述工厂模式,总是感觉无从说起,不知道怎么去定义工厂模式,反复看了几遍之后终于理解一点. 自己理解工厂模式是通过这两种模式的特点来理解和定义的 ...

  5. java 工厂方法_java设计模式-工厂方法模式

    1.工厂方法(FactoryMethod)模式的定义 定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中.这满足创建型模式中所要求的"创建与使用相分离" ...

  6. java策略模式_Java设计模式之策略模式详解

    本文实例为大家分享了Java策略模式,供大家参考,具体内容如下 1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下: Def ...

  7. java抽象工厂模式_JAVA设计模式-抽象工厂模式

    定义 抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构. 抽象工厂模 ...

  8. java bridge 模式_Java设计模式之桥模式(Bridge模式)介绍

    Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...

  9. java模板方法模式_java设计模式(模板方法模式)

    模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.通俗的说的就是有很多相同的步骤的,在某一些地方可能有一些差 ...

  10. java 模板模式_java设计模式之模板模式

    模板模式 模板模式(Template Pattern),定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤.这种类型的设计模式属于 ...

最新文章

  1. 面试人,想被面试,面试。。。
  2. C语言并发执行的进程怎么写,多进程并发写文件 多进程并发售票 用c语言写
  3. 烂泥:CentOS6.5挂载windows共享文件夹
  4. CSS之box-shadow
  5. Linux 技巧:让进程在后台可靠执行的几种方法
  6. SAP Cloud for Customer Price-计价简介 1
  7. VSAN见证虚拟设备
  8. conda安装tensorflow-gpu
  9. 上厕所时间超长也能被开除?法院:超出正常生理需求范围!
  10. SQLite学习总结(1)——SQLite简介及快速入门
  11. [Axis2与Eclipse整合开发Web Service系列之二] Top-Down方式,通过WSDL逆向生成服务端(续)
  12. 计算机网络基础知识笔记
  13. c语言倒计时不影响进程_初学C语言没有项目练手怎么行,这17个小项目收下不谢...
  14. 使用ViewModel模式来简化WPF的TreeView
  15. 怎么删除CSDN已上传的资源
  16. Call for Presentations!Flink Forward Global 2021 议题征集ing
  17. 求四科平均成绩c语言,c语言实验报告评语大全
  18. 基本数据结构----顺序表
  19. Asp.Net MVC4入门指南(7):给电影表和模型添加新字段
  20. 决策树应用实例③——银行借贷模型

热门文章

  1. CUDA error: device-side assert triggered
  2. 线性代数 06 克莱默法则
  3. Notepad++ 替代品开源了!
  4. JS复制input内容
  5. 对于初学者的JavaScript 教程
  6. 计算机硬件系统的主要性能指标
  7. Windows 11正式版来了!一文带你免费升级、镜像下载、最低系统要求
  8. MD5 32位加密
  9. 定义范围中的备选方案生成、横向思维、创建WBS、工作包定义、WBS、确认范围过程和实施质量过程的关系、联合应用设计和质量功能展开QFD...
  10. 权力的游戏中文字幕词云图