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. python删除目录下七天前创建的文件

    #coding=utf-8 import os import time import datetime def deleteOutdateFiles(path): """ ...

  2. 企业级web nginx服务优化

    1.1)隐藏nginx header 内版本号信息 [root@aliyun ~]# vi /application/nginx/conf/nginx.conf http{ …… server_tok ...

  3. SQLAlchemy_定义(一对一/一对多/多对多)关系

    目录 Basic Relationship Patterns One To Many One To One Many To Many Basic Relationship Patterns 基本关系模 ...

  4. HDU - 6397 Character Encoding 2018 Multi-University Training Contest 8 (容斥原理)

    题意:问有多少种不重复的m个数,值在[0,n-1]范围内且和为k. 分析:当k<=n-1时,肯定不会有盒子超过n,结果是C(m+k-1,k):当k>m*(n-1)时,结果是0. 剩下的情况 ...

  5. CSS的单位 及 css3的calc() 及 line-height 百分比

    CSS的单位及css3的calc()及line-height百分比 摘自:http://www.haorooms.com/post/css_unit_calc 单位介绍 说到css的单位,大家应该首先 ...

  6. iconfont的使用

    首先你要有一个图标库的账号,我们使用的是阿里矢量图标库,其次你要有一套已经设计好的图标原图.如果你具备了这些,就可以和我一起看iconfont的使用姿势了. 写在前面 不结合其他矢量库或UI框架一起使 ...

  7. Sybase:循环调用存储过程

    Sybase:循环调用存储过程 一.日期循环 declare @c_count int declare @rq int --获取两个日期之间的天数 ,getdate()) begin ,),),),) ...

  8. CSS3自定义发光radiobox单选框

    在线演示 本地下载

  9. 20145120黄玄曦《网络对抗》Web安全基础实践

    20145120黄玄曦<网络对抗>Web安全基础实践 回答问题 (1)SQL注入攻击原理,如何防御 SQL注入原理简单地说大概是,通过构造特殊的SQL命令提交表单,让服务器执行构造的恶意S ...

  10. LAMP脚本

    A goal is a dream with a deadline. Much effort, much prosperity. 环境:CentOS release 6.5  2.6.32-431.e ...