大话设计模式-->模板方法设计模式
在学习java的过程中,我们肯定听到过设计模式这名词,在行业中有这么一句话,若您能熟练的掌握23种设计模式,那么你便是大牛!
好了,废话不多说,今天我跟大家分享一下23种设计模式之一的 模板方法 设计模式
首先我们要知道什么是模板方法设计模式?
模板方法设计模式就是定义一个操作中的算法骨架,而将一些实现步骤延迟到子类当中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 为什么要使用模板方法设计模式?
模板方法模式是比较简单的一种设计模式,但是它却是代码复用的一项基本的技术,在类库中尤其重要,它遵循“抽象类应当拥有尽可能多的行为,应当拥有尽可能少的数据”的重构原则。作为模板的方法要定义在父类中,在方法的定义中使用到抽象方法,而只看父类的抽象方法是根本不知道怎样处理的,实际做具体处理的是子类,在子类中实现具体功能,因此不同的子类执行将会得出不同的实现结果,但是处理流程还是按照父类定制的方式。这就是模板方法的要义所在,制定算法骨架,让子类具体实现。 在什么情况下使用?
-->算法或操作遵循相似的逻辑
-->重构时(把相同的代码抽取到父类中) -->重要、复杂的算法,核心算法设计为模板算法 接下来我们来看看到底怎么才能实现模板方法设计模式
我们以饮料机为示例的原型,每台饮料机都可以制作出不同的饮料,如同一台饮料机可 制作咖啡 还可以 制作茶
假如:制作咖啡的步骤如下: 制作茶的步骤如下:
1.将水煮沸 1.将水煮沸
2.用沸水泡咖啡 2.用沸水将茶叶煮五到六分钟
3.将咖啡倒入杯中 3.将茶水倒入杯中
4.假如糖块或牛奶 4.加入柠檬或不加任何东西
那么,由上面的背景可见,我们制作咖啡和制作茶的步骤中 1 3是完全一致的,而2 4则是各自执行的各自的步骤
所有我们就可以设计一个模板,来规范制作过程
/*
* 抽象类 饮料机模板类
*/
public abstract class Template {
/*
* 制备饮料的模板方法
* 封装了所有子类的共同遵循的算法框架
*/
public final void driveTemplate(){ //这个模板必须用final修饰,因为不能允许子类修改这个模板框架,只能是修改特定的步骤
//1.将水煮沸
boilWater();
//2. 炮制饮料
blew();
//3. 倒入杯中
pourInCup();
//4. 进入调味料
addCondiments();
}
}
如上代码就是定义了一个制作饮料的模板,将具体的步骤都罗列出来了
因为我们的步骤1和步骤3都是相同的所以我们可以将其实现方法定义为私有的,以减少代码的复杂度,而步骤2和步骤4则可定义为抽象方法,其实现交由其子类完成
如:
/*
* 基本方法,将水煮沸
*/
private void boilWater() {
System.out.println("将水煮沸");
} /*
* 基本方法,倒入杯中
*/
private void pourInCup() {
System.out.println("倒入杯中");
} /*
* 抽象的基本方法 加入调味料
*/
public abstract void addCondiments(); /*
* 抽象的基本方法 炮制饮料
*/
public abstract void blew();
这样我们就定义好了一个模板方法了,我们可以通过创建一个子类来继承自这个模板,重新其抽象方法
如 制作咖啡
/*
* 制备咖啡的具体实现
*/
public class Coffee extends Template { //加入调味料
@Override
public void addCondiments() {
System.out.println("加入糖和牛奶");
} //炮制咖啡
@Override
public void blew() {
System.out.println("用沸水冲泡咖啡");
} }
或者是制作茶
/*
* 制备茶的具体实现
*/
public class Tea extends Template {
//添加调料
@Override
public void addCondiments() {
System.out.println("加入柠檬");
}
//冲泡茶
@Override
public void blew() {
System.out.println("用80度的热水浸泡茶叶5分钟");
} }
这样我们在测试类中就能很清楚的看到结果了
//测试类
public class Test {
public static void main(String[] args) {
System.out.println("制备咖啡");
Template t1=new Coffee();
t1.driveTemplate();
System.out.println("咖啡制备完成");
System.out.println("=====================");
System.out.println("制备茶");
Template t2=new Tea();
t2.driveTemplate();
System.out.println("制备茶完成");
}
}
测试结果如图

当然,如果我们现在有另外一种需求呢?就是我制作茶的时候不想要添加任何东西,这时候我们使用上面的方法是没法完成的,这时候我们就引出了
模板方法设计模式中的另一个名词, 钩子函数
我们可以使用钩子函数来判断是否要执行某一步的操作
如:
/*
* 抽象类 饮料机模板类
*/
public abstract class Template {
/*
* 制备饮料的模板方法
* 封装了所有子类的共同遵循的算法框架
*/
public final void driveTemplate(){ //这个模板必须用final修饰,因为不能允许子类修改这个模板框架,只能是修改特定的步骤
//1.将水煮沸
boilWater();
//2. 炮制饮料
blew();
//3. 倒入杯中
pourInCup(); //钩子函数进行判定(例如茶不想加入调味料)
if(isRight()){
//4. 进入调味料
addCondiments();
}
} /*
* 基本方法,将水煮沸
*/
private void boilWater() {
System.out.println("将水煮沸");
} /*
* 基本方法,倒入杯中
*/
private void pourInCup() {
System.out.println("倒入杯中");
} /*
* 抽象的基本方法 加入调味料
*/
public abstract void addCondiments(); /*
* 抽象的基本方法 炮制饮料
*/
public abstract void blew(); //钩子函数 判断用户是否要执行某些功能
public boolean isRight(){
return true;
} }
假如在制作茶的时候不想加任何东西,那么我们只需要在制作茶的子类中将钩子函数重写即可
/*
* 制备茶的具体实现
*/
public class Tea extends Template {
//添加调料
@Override
public void addCondiments() {
System.out.println("加入柠檬");
}
//冲泡茶
@Override
public void blew() {
System.out.println("用80度的热水浸泡茶叶5分钟");
}
//重写钩子函数 改变其值
@Override
public boolean isRight(){
return false;
} }
这样的执行结果如图

这样就完成了我们的需求了 以上就是模板方法设计模式中的内容了,其他设计模式会在后续学到后再跟大家分享分享~~
注:本人也是初学者,所以写得不好的地方望各位大牛勿怪,有不足的地方还望指出来,欢迎讨论!
大话设计模式-->模板方法设计模式的更多相关文章
- Java设计模式——模板方法设计模式(abstract修饰)
解释: 一个抽象类中,有一个主方法,再定义 1...n 个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用. 解决的问题: 当功能内部一 ...
- 设计模式-模板方法设计模式--Template Method design pattern
/** * Abstract implementation of the {@link org.springframework.context.ApplicationContext} * interf ...
- linkin大话设计模式--模板方法模式
linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...
- 从Spring HibernateTemplate模板方法设计模式的实现谈起
概述 模板方法模式是GOF设计模式中很典型的设计模式,其意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用.Spring模板方法模式实际是模板方法模式 ...
- Java抽象类深入理解-----模板方法设计模式(Templete Method)
模板方法设计模式(Templete Method) 定义一个操作中的算法骨架,而将一些可变部分的实现延迟到子类中. 模板方法设计模式使得子类可以不改变一个算法的结构即可重新定义该算法某些特定的步骤. ...
- javascript设计模式——模板方法模式
前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...
- 设计模式 | 模板方法模式(template method)
定义: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构:(书中图,侵删) 一个定义整体框架的父类 若干不同具体实现 ...
- 结合JDK源码看设计模式——模板方法模式
前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
随机推荐
- Visual Studio 2010配置Opencv2.4.9
转自: http://blog.csdn.net/huang9012/article/details/21811129 这篇文章作为OpenCV的启程篇,自然少不了先系统地介绍OpenCV开发环境的配 ...
- [转]Linux下的lds链接脚本详解
转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml 一. 概论 每一个链接过程都由链接脚本(lin ...
- 将数据库表导入到solr索引
将数据库表导入到solr索引 编辑solrcofnig.xml添加处理器 <requestHandler name="/dataimport" class="org ...
- AIDL示例
背景 最近在考虑项目重构的时候,考虑将项目拆分成两个APK,一个用于数据服务,一个用于UI展示. 数据服务APK向自己编写APK提供数据,同时也可以向第三方提供数据.考虑使用这样的方式代替向第三方提供 ...
- dlib库使用
最近的工作中用到了dlib这个库,该库是一个机器学习的开源库,使用起来很方便,直接包含头文件即可,并且不依赖于其他库(自带图像编解码库源码).不过由于是开源的,所以bug多少有一些,我在example ...
- C#参考:Linq 概述
Linq (Language Integrated Query,语言集成查询),是微软公司提供的一项新技术,它能够将查询功能引入到.NET 3.5 所支持的编程语言中,例如C#,Visual Basi ...
- Warning: Multiple build commands for output file /xxx
xcode中 有时候会报一个警告: [WARN]Warning: Multiple build commands for output file /xxx 要解决这个问题很简单: 1.选择你的工程 2 ...
- xfire框架内部基本结构解析
1 概述 xfire是webservice的一个实现框架,是apache旗下CXF的前身,是一个比较被广泛使用的webservice框架,网上有很多关于如何使用xfire或cxf的hello worl ...
- IMongoQuery的内部实现Query的用法
Query.All("name", "a", "b");//通过多个元素来匹配数组 Query.And(Query.EQ("nam ...
- rabbitmq使用dead letter机制来进行retry
首先建立 工作exchange和工作queue,指定工作队列的x-dead-letter-exchange到重试exchenge var workQueueArgs = new Dictionary& ...