在读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. tech blog link

    http://amitsaha.github.io/site/notes/index.html

  2. android 获取屏幕宽高 和 获取控件坐标

    一.获取屏幕宽高: (1). WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE); int width ...

  3. SolidEdge如何复制特征 建立类似于UG 块的概念

    直接Ctrl+C和Ctrl+V可以实现特征的复制粘贴   按N键可以改变特征方向 已经复制完成的特征要进行定位,则右击该特征,编辑轮廓,可以进行聪慧尺寸的标注   使用特征库的方式,就像UG的块一样, ...

  4. 【iOS开发系列】cell切割线置顶

    废话不多说,直接上代码: /** * tableViewCell切割线左側置顶 < 1 > */ -(void)viewDidLayoutSubviews { if ([_tableVie ...

  5. 我对hibernate和mybatis框架的比較

    系统在选择操作数据库的框架上面,究竟是选择hibernate,还是mybatis. 首先说下两者的原理,假设你要关联几张表做查询,查出20条记录: 1.假设是mybatis SELECT *   FR ...

  6. u-boot简单学习笔记(一)

    一:Bootloader启动结构:      由于 Boot Loader 的实现依赖于 CPU 的体系结构,因此大多数 Boot Loader 都分为 stage1 和 stage2 两大部分.依赖 ...

  7. 还在为开发APP发愁? 这里就有现成通用的代码!

    1.开源控件 1)首页: 1.1)首先是下拉刷新数据的 SwipeRefreshLayout 地址:https://github.com/hanks-zyh/SwipeRefreshLayout 1. ...

  8. eclipse配置android

    先在eclipse中安装ADT插件,install内点击add,name:ADT, URL:http://dl-ssl.google.com/android/eclipse/ 之后直接finish就好 ...

  9. VUE 之 路由 VueRouter

    1.VueRouter的安装 1.1.https://unpkg.com/vue-router/dist/vue-router.js下载安装. 1.2.<script src="./s ...

  10. Mac版idea使用总结

    1.设置文档注释快捷键:快捷键设置里搜索 Fix doc comment 2.IDEA不显示项目project视图(转载于 https://blog.csdn.net/oyimiyangguang12 ...