1>模板模式定义了算法的步骤,把这些步骤的实现延续到子类

2>模板模式为我们提供了一个代码复用的技巧

3>模板抽象类中可以定义具体方法、抽象方法和钩子方法

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

5>钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择要不要实现它

模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情冴下,重新定义算法中的某些步骤。

我们使用冲泡咖啡和冲泡茶的例子

加工流程:

咖啡冲泡法:1.把水煮沸、2.用沸水冲泡咖啡、3.把咖啡倒进杯子、4.加糖和牛奶

茶冲泡法:   1.把水煮沸、2.用沸水冲泡茶叶、3.把  茶 倒进杯子、4.加蜂蜜

实践步骤:

1>创建一个模板(抽象)类:Beverage(饮料)

  1. package com.kaishengit.beverage;
  2. public abstract class Beverage {
  3. /**
  4. * 冲泡咖啡或茶...流程
  5. */
  6. public final void create(){
  7. boilWater();//把水煮沸
  8. brew();//用沸水冲泡...
  9. pourInCup();//把...倒进杯子
  10. addCoundiments();//加...
  11. }
  12. public abstract void addCoundiments();
  13. public abstract void brew();
  14. public void boilWater() {
  15. System.out.println("煮开水");
  16. }
  17. public void pourInCup() {
  18. System.out.println("倒进杯子");
  19. }
  20. }

2>创建一个咖啡类(Coffee)和茶(Tea)类,都继承Beverage抽象类

1.咖啡(Coffee)

  1. package com.kaishengit.beverage;
  2. public class Coffee extends Beverage{
  3. @Override
  4. public void addCoundiments() {
  5. System.out.println("添加糖和牛奶");   }
  6. @Override
  7. public void brew() {
  8. System.out.println("用水冲咖啡");
  9. }
  10. }

2.茶(Tea)

  1. package com.kaishengit.beverage;
  2. public class Tea extends Beverage{
  3. @Override
  4. public void addCoundiments() {
  5. System.out.println("添加蜂蜜");
  6. }
  7. @Override
  8. public void brew() {
  9. System.out.println("用水冲茶");
  10. }
  11. }

3.我们测试一下:

  1. package com.kaishengit.beverage;
  2. public class Test {
  3. public static void main(String[] args) {
  4. Coffee coffee = new Coffee();
  5. coffee.create();//冲泡咖啡
  6. //Tea tea = new Tea();//冲泡茶
  7. //tea.create();
  8. }
  9. }

运行结果:

-----------------------------------

煮开水

用水冲咖啡

倒进杯子

添加糖和牛奶

-----------------------------------

在模版模式中使用挂钩(hook)

存在一个空实现的方法,我们称这种方法为”hook”。子类可以视情况来决定是否要覆盖它。

1>我们对模板类(Beverage)进行修改

  1. package com.kaishengit.beverage;
  2. public abstract class Beverage {
  3. /**
  4. * 冲泡咖啡或茶...流程
  5. */
  6. public final void create(){
  7. boilWater();//把水煮沸
  8. brew();//用沸水冲泡...
  9. pourInCup();//把...倒进杯子
  10. addCoundiments();//加...
  11. hook();//挂钩
  12. }
  13. //空实现方法
  14. public void hook(){}
  15. public abstract void addCoundiments();
  16. public abstract void brew();
  17. public void boilWater() {
  18. System.out.println("煮开水");
  19. }
  20. public void pourInCup() {
  21. System.out.println("倒进杯子");
  22. }
  23. }

2>假如我们搞活动,喝一杯咖啡送一杯,修改咖啡(Coffee)类

  1. package com.kaishengit.beverage;
  2. public class Coffee extends Beverage{
  3. @Override
  4. public void addCoundiments() {
  5. System.out.println("添加糖和牛奶");   }
  6. @Override
  7. public void brew() {
  8. System.out.println("用水冲咖啡");
  9. }
  10. /**
  11. * 挂钩
  12. */
  13. @Override
  14. public void hook() {
  15. System.out.println("再来一杯");
  16. }
  17. }

3>使用上面的测试类

运行结果:

--------------------------------

煮开水

用水冲咖啡

倒进杯子

添加糖和牛奶

再来一杯

--------------------------------

结果中有“再来一杯”...

我们也可以这样使用挂钩,让其决定里面的代码是否执行

1>我们对模板类(Beverage)进行修改

  1. package com.kaishengit.beverage;
  2. public abstract class Beverage {
  3. /**
  4. * 冲泡咖啡或茶...流程
  5. */
  6. public final void create(){
  7. boilWater();//把水煮沸
  8. brew();//用沸水冲泡...
  9. pourInCup();//把...倒进杯子
  10. //挂钩决定是否添加配料
  11. if(hook()){
  12. addCoundiments();//加...
  13. }
  14. //hook();
  15. }
  16. /**
  17. * 默认添加配料
  18. * @return
  19. */
  20. public boolean hook() {
  21. return true;
  22. }
  23. //public void hook(){}
  24. public abstract void addCoundiments();
  25. public abstract void brew();
  26. public void boilWater() {
  27. System.out.println("煮开水");
  28. }
  29. public void pourInCup() {
  30. System.out.println("倒进杯子");
  31. }
  32. }

2>我们对Coffee类进行修改,让其不添加配料

  1. package com.kaishengit.beverage;
  2. public class Coffee extends Beverage{
  3. @Override
  4. public void addCoundiments() {
  5. System.out.println("添加糖和牛奶");   }
  6. @Override
  7. public void brew() {
  8. System.out.println("用水冲咖啡");
  9. }
  10. /**
  11. * 有的客人不喜欢加配料
  12. */
  13. @Override
  14. public boolean hook() {
  15. return false;
  16. }
  17. /*@Override
  18. public void hook() {
  19. System.out.println("再来一杯");
  20. }
  21. */
  22. }

3>还是使用上面的测试类

运行结果:

------------------------------------------------------

煮开水

用水冲咖啡

倒进杯子

------------------------------------------------------

运行结果中没有添加配料

关于模板模式

1>模板模式定义了算法的步骤,把这些步骤的实现延迟到子类

2>模板模式为我们提供了一个代码复用的技巧

3>模板抽象类中可以定义具体方法、抽象方法和钩子方法

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

5>钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择要不要实现它

Template pattern模板方法模式的更多相关文章

  1. 设计模式13:Template Method 模板方法模式(行为型模式)

    Template Method 模板方法模式(行为型模式) 变与不变 变化——是软件永恒的主题,如何管理变化带来的复杂性?设计模式的艺术性和复杂度就在于如何分析,并发现体系中的变化点和稳定点,并使用特 ...

  2. 设计模式 : Template method 模板方法模式 -- 行为型

      设计模式中,模板模式面向的是方法级别的流程.(不过好像世界上大部分问题,都可以抽象点.抽象点吧,最后抽象到一个方法里面吧.) 1. 一个方法,可以用来描述一个流程,这个流程涉及多个环节,不同环节可 ...

  3. Template Method - 模板方法模式

    1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序.但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关.例子1: ...

  4. 设计模式(22)--Template Method(模板方法模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声 ...

  5. 设计模式学习笔记——Template Method模板方法模式

    可能是最简单的设计模式. 而且你我都用过而不自知. 因为,模板方法模式也者,就是面向对象中的继承.公用部分放在父类,子类继承父类,然后扩展.呵呵.

  6. 设计模式C++学习笔记之九(Template Method模板方法模式)

      模板模式也是相当简单的一种模式,而且是比较常用的.模板模式是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些 ...

  7. 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)

    今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...

  8. 深入浅出设计模式——模板方法模式(Template Method Pattern)

    模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...

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

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

随机推荐

  1. 简单的 H5 视频推流解决方案

    导语 随着直播平台爆发式增长,直播平台从 PC 端转战移动端,紧跟着直播的潮流,自己学习实现了一套简单的 H5 视频推流的解决方案,下面就给小伙伴们分享一下自己学习过程中的经验. 环境部署 1. 配置 ...

  2. 记一次centos7挂在nas盘的踩坑经过

    p:first-child, #write > ul:first-child, #write > ol:first-child, #write > pre:first-child, ...

  3. 简明python教程

    linux查询python版本:python -V linux进入python:python 退出python:CTRL+D 使用源文件:helloworld.py 运行这个程序:python hel ...

  4. python-绘图matplotlib

    <Python编程:从入门到实践>读书笔记 1.使用plot()绘制简单的折线图 import matplotlib.pyplot as plt va=[1,2,3,4,5] sq=[1, ...

  5. Java泛型二:通配符的使用

    原文地址http://blog.csdn.net/lonelyroamer/article/details/7927212 通配符有三种: 1.无限定通配符   形式<?> 2.上边界限定 ...

  6. xlrd,xlwt操作Excel实例

    把有合并单元格的信息读取出来,输出所在层数与位置 我要操作的Excel是这样的 要的到的是这样的效果 # -*- coding: utf-8 -*- import xlrd import xlwt r ...

  7. Delphi 正则表达式之TPerlRegEx 类的属性与方法(7): Split 函数

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(7): Split 函数 //字符串分割: Split var   reg: TPerlRegEx;   List: TStrings; ...

  8. Mac 一键显示所有隐藏文件 不要那么六好吧

    系统应简洁而有效,对一般用户来说这一点尤为重要.不必要让普通用户知道的信息往往会给他们造成困扰,因而,隐藏掉他们便是个不错的选择,既可以保证系统平稳流畅运行,也可以为用户提供友好界面. 对于开发者而言 ...

  9. Node单线程与异步编程的初步理解

    最近学习了一些关于node的单线程与异步的知识,想拿过来和大家分享下: var async = require('async') //并行无关联,等待事件为最长时间请求过程.如以下两个任务执行时间 c ...

  10. 解决hive交互模式退格键乱码

    在hive的交互模式下,输入退格.方向键等,出现乱码,可以通过如下方法解决: 1.修改bashrc文件: vi ~/.bashrc 在文件最后添加一行: stty erase ^H. 2.使修改生效: ...