在读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. Spring boot 整合spring Data JPA+Spring Security+Thymeleaf框架(上)

    近期上班太忙所以耽搁了给大家分享实战springboot 框架的使用. 以下是spring boot 整合多个框架的使用. 首先是准备工作要做好. 第一  导入框架所需的包,我们用的事maven 进行 ...

  2. [转]Visual Studio 2012 编译错误【error C4996: 'scanf': This function or variable may be unsafe. 】的解决方案

    原文地址:http://www.cnblogs.com/gb2013/archive/2013/03/05/SecurityEnhancementsInTheCRT.html 在VS 2012 中编译 ...

  3. php 中函数获取可变参数的方法, 这个语法有点像 golang 语言中的

    原文呢:http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration.strict Onl ...

  4. 【Discuz】ucenter通讯失败与Discuz的头像无法显示

    假设是Discuz论坛的一些小样式图片.仅仅须要升级一下Discuz论坛的论坛或者,直接把整个网站的css的首域名替换一下.比方将127.0.0.1:8080/..开头的东西全改成127.0.0.1: ...

  5. 一篇很好的讲解SIFT算法的文章

    http://blog.csdn.net/zddblog/article/details/7521424

  6. hiberinate二级缓存

    hibernate.cfg.xml配置 <!-- 二级缓存类型 --> <property name="hibernate.cache.region.factory_cla ...

  7. Redis实现消息的发布/订阅

    利用spring-boot结合redis进行消息的发布与订阅: 发布: class Publish { private static String topicName = “Topic:chat”; ...

  8. BZOJ 4197: [Noi2015]寿司晚宴 状态压缩 + 01背包

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿 ...

  9. xamarin.android Activity之间跳转与传值

    前言 由于需要,所以接触到这个新的安卓开发模式,我会把我的学习经历全都记录下来,希望对大家有用. 导读 关于Activity,学习过安卓的人也应该明白什么是Activity,推荐新手去看YZF的这篇文 ...

  10. cocos2d-x交叉编译到安卓

    ccocos2d-x是一个基于MIT协议的开源框架,用于构建游戏.应用程序和其它图形界面交互应用. 它的最大特点就是跨平台性,支持IOS, Android.Windows, WindowsPhone等 ...