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. 0503-Hystrix保护应用-feign的hystrix支持

    一.概述 1.1.基础[示例一] 如果Hystrix在类路径上并且feign.hystrix.enabled = true,Feign将用断路器包装所有方法.还可以返回com.netflix.hyst ...

  2. php 获取各类时间归类

    //php获取今日开始时间戳和结束时间戳 $beginToday=mktime(0,0,0,date('m'),date('d'),date('Y')); $endToday=mktime(0,0,0 ...

  3. bootstrap基本使用

    bootstrap是封装了css和js代码实现酷炫的效果,所以使用的时候,比如说是列表效果,直接调用它本身定义的函数就ok了 静态文件 把href='..static/..'里面改为url_for静态 ...

  4. Java全局变量

    全局变量:Java程序中,不能在所有类之外定义全局变量,只能通过在一个类中定义公用.静态的变量来实现一个全局变量.例如:ClassGlobalVar{public static global_var; ...

  5. PL/SQL编程—分页功能(存储过程)

    SQL),bookname ),publish )); Table created SQL> SQL> create or replace procedure sp_add_book(bo ...

  6. Codeforces Round #395 (Div. 2) C. Timofey and a tree

    地址:http://codeforces.com/contest/764/problem/C 题目: C. Timofey and a tree time limit per test 2 secon ...

  7. hdu1711 Number Sequence kmp应用

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目: Problem Description Given two sequences of n ...

  8. CSS小知识---table表格

    所用的仍是bootstrap的模板 <link rel="stylesheet" href="css/bootstrap.min.css"> < ...

  9. for_each用法

    for_each()是个function template #include <algorithm>头文件说明 template<class _InIt, class _Fn1> ...

  10. List To Json

    命名空间 using Newtonsoft.Json; 实例代码 /// <summary> /// 将list集合转换为json /// </summary> /// < ...