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. 【ORACLE】10步全然卸载CRS

    版权声明:本文为博主原创文章(原文:blog.csdn.net/clark_xu 徐长亮的专栏),未经博主同意不得转载. https://blog.csdn.net/u011538954/articl ...

  2. Hadoop十年解读与发展预测

    编者按:Hadoop于2006年1月28日诞生,至今已有10年,它改变了企业对数据的存储.处理和分析的过程,加速了大数据的发展,形成了自己的极其火爆的技术生态圈,并受到非常广泛的应用.在2016年Ha ...

  3. php源码安装,并配置apache支持php

    一.php安装准备环境 yum install zlib libxml libjpeg freetype libpng gd curl libiconv zlib-devel libxml2-deve ...

  4. 查看虚拟机操作系统、cpu核数、内存命令

    1.查看操作系统 在终端中执行下列指令:cat/etc/issue可以查看当前正在运行的 Ubuntu 的版本号.其输出结果类似下面的内容:Ubuntu 10.04 LTS \n \l方法二:使用 l ...

  5. python网络编程——IO多路复用之select

    1 IO多路复用的概念 原生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收发数据(调用recv.send.sendall)时也是阻塞的.原生so ...

  6. module.exports和exports得区别

    对module.exports和exports的一些理解 可能是有史以来最简单通俗易懂的有关Module.exports和exports区别的文章了. exports = module.exports ...

  7. 【JavaScript】键盘控制小球

    参考: 1.Simple Canvas Game 2.javaScript 事件监听 <!DOCTYPE html> <html> <head> <meta ...

  8. jQuery动画二级下拉菜单

    在线演示 本地下载

  9. RN项目中缩进处理

    SpannableString使用详解http://blog.csdn.net/u012702547/article/details/49895157 Spannable的用法http://www.j ...

  10. void及void指针介绍【转】

    本文转载自:http://blog.csdn.net/renren900207/article/details/20769503 void类型指针(如void *p)所指向的数据类型不是确定的,或者说 ...