在学习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;
} }
 

这样的执行结果如图

 
这样就完成了我们的需求了 以上就是模板方法设计模式中的内容了,其他设计模式会在后续学到后再跟大家分享分享~~
注:本人也是初学者,所以写得不好的地方望各位大牛勿怪,有不足的地方还望指出来,欢迎讨论!

大话设计模式-->模板方法设计模式的更多相关文章

  1. Java设计模式——模板方法设计模式(abstract修饰)

    解释: 一个抽象类中,有一个主方法,再定义 1...n 个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用. 解决的问题: 当功能内部一 ...

  2. 设计模式-模板方法设计模式--Template Method design pattern

    /** * Abstract implementation of the {@link org.springframework.context.ApplicationContext} * interf ...

  3. linkin大话设计模式--模板方法模式

    linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...

  4. 从Spring HibernateTemplate模板方法设计模式的实现谈起

    概述 模板方法模式是GOF设计模式中很典型的设计模式,其意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用.Spring模板方法模式实际是模板方法模式 ...

  5. Java抽象类深入理解-----模板方法设计模式(Templete Method)

    模板方法设计模式(Templete Method) 定义一个操作中的算法骨架,而将一些可变部分的实现延迟到子类中. 模板方法设计模式使得子类可以不改变一个算法的结构即可重新定义该算法某些特定的步骤. ...

  6. javascript设计模式——模板方法模式

    前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...

  7. 设计模式 | 模板方法模式(template method)

    定义: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构:(书中图,侵删) 一个定义整体框架的父类 若干不同具体实现 ...

  8. 结合JDK源码看设计模式——模板方法模式

    前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...

  9. 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查

    原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...

随机推荐

  1. brew 出现 git 错误的问题分析

    现象 brew update的时候出现 gitcrash   分析 在brew update 的时候看见有 git gc 的字样,提示有在gc 的动作.到/usr/local/ 目录,直接运行 git ...

  2. CSS选择器实现搜索功能 驱动过滤搜索技术

    一.CSS选择器可以用来实现搜索功能 CSS选择器可以用来实现搜索功能. 作者以前提过CSS3的选择器结合表单元素可以用来控制元素的显隐,这里,类似的,还是CSS3的选择器,用来过滤和搜索页面元素. ...

  3. Android手机的 storage

    老外的一段解释 -------------------------------------------------------------------------------------------- ...

  4. Golang pprof heap profile is empty

    Q: When you use `go tool pprof` get heap data, profile is empty. A: The default sampling rate is 1 s ...

  5. android自定义RadioGroup实现可以添加多种布局

    android自带的RadioGroup是继承自LinearLayout,如果布局的时候不是直接写radiobutton,即radiobutton外面还包了一层容器,这时分组是不成功的,因为查找不到r ...

  6. saiku执行速度慢

    使用saiku的过程中发现一个重要问题,速度慢!下面是跟踪和优化过程 一.首先抓包,发现ajax请求:http://l-tdata2.tkt.cn6.qunar.com:8080/saiku/rest ...

  7. [LeetCode] Remove Invalid Parentheses

    This problem can be solved very elegantly using BFS, as in this post. The code is rewritten below in ...

  8. linux下mysql的root密码忘记解决方法

    1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ...

  9. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  10. 读书笔记_Effective_C++_条款四十三:学习处理模板化基类的名称

    背景是这样的,有两个不同的公司,然后想设计一个MessageSender,为这两个公司发送不同的消息,既支持明文发送SendClearText,也支持密文发送SendEncryptedText.一种思 ...