在读Spring源码的时候,发现Spring代码中运用了大量的模板模式,比如根据文件系统目录加载配置文件(FileSystemXmlApplicationContext),类路径加载配置文件(ClassPathXmlApplicationContext),以及根据项目上下文目录(XmlWebApplicationContext)加载配置文件。这个在加载的过程中就使用了模板设计模式,所以特意去学习了一下模板设计模式,从而更好的理解源码。

1.模板设计模式在书中的定义

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

  我的翻译就是:完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。

2.举个例子来说

  小张的团队最近接受一个需求,实现实现一家咖啡店的冲泡咖啡和茶的冲泡自动化。之前这家咖啡店都是由咖啡师傅手动进行调制咖啡和茶。现在咖啡店需要引入自动化的点单和调制饮料的系统,小张负责实现调制饮料的功能。

  咖啡师傅手工冲泡咖啡和茶的流程:

  冲泡咖啡:

         把水煮沸

用沸水冲泡咖啡

把咖啡倒入杯子

加糖和牛奶

  冲泡茶:

把水煮沸

用沸水冲泡茶叶

把茶倒入杯子

加柠檬

  使用模板模式实现

  我们首先看一个类图

  

  代码实现

package xuelongjiang.designpartten.templatemethod;

/**
*
* 模板方法
*
*
*/
abstract public class CaffeineBeverage { //算法。 抽象类的算法是final 的不允许被子类修改
public final void prepareRecipe(){ //算法的具体步骤
boilWater(); //烧水
brew();//冲泡
pourInCup();// 把饮料倒入杯子
if(hook()){
addCondiments();// 加调料
} } public abstract void brew(); public abstract void addCondiments(); public void boilWater(){ System.out.println("烧水");
} public void pourInCup(){
System.out.println("把饮料倒入杯子");
} /**
* 钩子,具体实现可以对算法步骤做一些控制
*
* @return
*/
public boolean hook(){
return true;
} }

  可以看到我们在冲泡咖啡/茶的抽象类中有一个hook方法,这个方法就是钩子方法。默认返回true,如果冲泡咖啡默认是加调料的那么子类就不用重写hook方法。

  咖啡类

package xuelongjiang.designpartten.templatemethod;

/**
*咖啡类
*/
public class Coffee extends CaffeineBeverage { @Override
public void brew() {
System.out.println("用沸水冲泡咖啡粉");
} @Override
public void addCondiments() {
System.out.println("加糖和牛奶");
} @Override
public boolean hook() {
return super.hook();
}
}

  茶类

package xuelongjiang.designpartten.templatemethod;

/**
* 茶类
*/
public class Tea extends CaffeineBeverage { @Override
public void brew() {
System.out.println("用沸水侵泡茶叶");
} @Override
public void addCondiments() {
System.out.println("加柠檬");
} @Override
public boolean hook() {
return super.hook();
}
}

  测试类

package xuelongjiang.designpartten.templatemethod;
/**
* 测试类
*/
public class TemplateMethodTest { public static void main(String[] args) {
CaffeineBeverage caffeineBeverage = new Tea();
caffeineBeverage.prepareRecipe(); System.out.println("-------------------"); caffeineBeverage = new Coffee();
caffeineBeverage.prepareRecipe(); }
}

  

  要点    

    好莱坞原则:别调用(打电话给)我们,我们会调用(打电话给)你。(即高层组件对低层组件的方式是:别调用我们,我们会调用你们)。

    模版方法定义了算法的步骤,把这些步骤的实现延迟到了子类。

    模版方法模式为我们提供了一种代码复用的重要技巧。

    模版方法的抽象类可以定义具体方法、抽象方法和钩子。

    抽象方法由子类实现。

    为了防止子类改变模版方法中的算法,可以将模版方法声明为final

---------------------
代码部分参考:https://blog.csdn.net/u013565163/article/details/79285617

设计模式——模板模式(Template Pattern)的更多相关文章

  1. 设计模式之模板模式 template

    设计模式 模板模式如果有一个流程如下step1();step2();step3();step4();step5();其中step3() step5()是需要用户自己编写使用其他步骤是固定的那么可以写成 ...

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

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

  3. 12. 星际争霸之php设计模式--模板模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  4. 《JAVA设计模式》之模板模式(Template)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述模板方法(Template Method)模式的: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式 ...

  5. 设计模式:模版模式(Template Pattern)

    android中的Activity框架,View框架中大量的on函数基本上都应用到了Template模式,掌握这一模式对于理解这些框架大有裨益. 模版模式 又叫模板方法模式,在一个方法中定义一个算法的 ...

  6. 设计模式 - 模板方法模式(template method pattern) JFrame 具体解释

    模板方法模式(template method pattern) JFrame 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(templ ...

  7. 设计模式 - 模板方法模式(template method pattern) 排序(sort) 具体解释

    模板方法模式(template method pattern) 排序(sort) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(tem ...

  8. 设计模式 - 模板方法模式(template method pattern) 具体解释

    模板方法模式(template method pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 模板方法模式(template metho ...

  9. 设计模式:模版模式(Template Pattern)-转

    模版模式 又叫模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情冴下,重新定义算法中的某些步骤. 我们使用冲泡咖啡和冲泡茶的例子 加工流程 ...

随机推荐

  1. 使用Myeclipse + SVN + TaoCode 免费实现项目版本控制的详细教程

    通过Myeclipse + SVN插件 + TaoCOde可以省去代码仓库的租建:同时还可以很好的满足小团队之间敏捷开发的需求.接下来详细介绍整个搭建流程. 首先,介绍所用到的工具: 1,Myecli ...

  2. iOS开发 当前时间 时间戳 转换

    1.今天在做一个webservice的接口的时候,被要求传一个时间戳过去,然后就是开始在Google上找 2.遇到两个问题,一,当前时间转化为时间戳,二,获取的当前时间和系统的时间相差8个小时 一,转 ...

  3. Office转SWF的一些感想(Office2007和Office2010)

    Office2007需要借助SaveAsPDFandXPS的插件完成,Office2010可以直接兼容. Office2PDF主要采用的是 Microsoft.Office.Interop的方式进行, ...

  4. struts.xml中为什么加上<constant name="struts.devMode" value="true" />就出错

    严重: Exception starting filter struts2 java.lang.NullPointerException at com.opensymphony.xwork2.util ...

  5. hunnu--11545--小明的烦恼——找路径

    小明的烦恼--找路径  Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:32768KB Total submit users:  ...

  6. PHP中include路径修改

    1.__FILE__ __FILE__ always equals to the real path of a php script regardless whether it's included. ...

  7. openwrt - squashfs-sysupgrade.bin 的生成过程

    squashfs-sysupgrade.bin 生成过程图 路径变量 $(KERNEL_BUILD_DIR)="/home/sam/Projects/openwrt-mt7620n/buil ...

  8. A new session could not be created. (Original error: Requested a new session but one was in progress) )错误解决办法

    z在desiredCapabilities里新增这俩居然fix了问题,原因暂时不得而知: capabilities.setCapability("unicodeKeyboard", ...

  9. LeetCode(21)题解:Merge Two Sorted Lists

    https://leetcode.com/problems/merge-two-sorted-lists/ Merge two sorted linked lists and return it as ...

  10. scala快速学习笔记(一):变量函数,操作符,基本类型

    为了用spark,先学下scala. 参考教程:http://meetfp.com/zh/scala-basic doc查询:http://docs.scala-lang.org 其它资料:http: ...