Template pattern模板方法模式

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

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

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

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

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

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

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

加工流程:

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

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

实践步骤:

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

Java代码  

  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)

Java代码  

  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)

Java代码  

  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.我们测试一下:

Java代码  

  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)进行修改

Java代码  

  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)类

Java代码  

  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)进行修改

Java代码  

  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类进行修改,让其不添加配料

Java代码  

  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>钩子是一种方法,它在抽象类中不做事,或只做默认的事,子类可以选择要不要实现它

时间: 2024-10-10 13:58:47

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

设计模式 ( 二十 ): Template method模板方法模式 -- 行为型

  1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序.但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关.例子1:银行业务办理流程在银行办理业务时,一般都包含几个基本固定步骤:取号排队->办理具体业务->对银行工作人员进行评分.取号取号排队和对银行工作人员进行评分业务逻辑是一样的.但是办理具体业务是个不相同的,具体业务可能取款.存款或者转账. 2.问题 如何保证架构逻辑的正常执行,而不被子类破坏 ? 3.

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

Template Method 模板方法模式(行为型模式) 变与不变 变化——是软件永恒的主题,如何管理变化带来的复杂性?设计模式的艺术性和复杂度就在于如何分析,并发现体系中的变化点和稳定点,并使用特定的设计方法来应对这种变化. 动机(Motivation) 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固定的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现. 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期

设计模式(八)the Template method 模板方法模式(类行为型)

1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序.但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关. 例子1:银行业务办理流程 在银行办理业务时,一般都包含几个基本固定步骤: 取号排队->办理具体业务->对银行工作人员进行评分. 取号取号排队和对银行工作人员进行评分业务逻辑是一样的.但是办理具体业务是个不相同的,具体业务可能取款.存款或者转账. 2.问题 如何保证架构逻辑的正常执行,而不被子类破坏 ?

Template Method (模板方法模式)

要想实现 模板方法模式,涉及到两个角色:1.抽象模板角色---父类(抽象的) 2.具体模板角色---子类 就是父类和子类继承的表现 抽象模板角色这个类里 定义了几个抽象方法,供子类去实现具体操作,还定义了一个模板方法(template),以告诉子类去实现这些方法要有一定的顺序去执行, 这种设计模式在JUnit中的setUp(),runTest(),tearDown()体现了, 源码: public void runBare() throws Throwable { setUp(); try {

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

模板方法模式(template method pattern) JFrame 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), Java的JFrame使用模板方法模式, paint()是能够覆盖的方

设计模式 - 模板方法模式(template method pattern) JFrame 详解

模板方法模式(template method pattern) JFrame 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), Java的JFrame使用模板方法模式, paint()是可以覆盖的方法,

设计模式 - 模板方法模式(template method pattern) Applet 详解

模板方法模式(template method pattern) Applet 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式(template method pattern), applet就是一个能够在网页上面执行的小程序, applet有很多钩子(

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

今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知,醋溜土豆丝,好吃不上火.清炒苦瓜这道菜好啊,更是夏天必备之良菜,其功效在此就不做过多赘述了.言归正传,上篇博客我们从“小弟”中学习了“外观模式”,我们也把“外观模式”戏称为“小弟模式”.今天我们要从醋溜土豆丝和清炒苦瓜的制作过程中来学习一下我们今天博客的主题“模板方法模式”(Template Me

设计模式 - 模板方法模式(template method pattern) 排序(sort) 详解

模板方法模式(template method pattern) 排序(sort) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考模板方法模式(template method pattern): http://blog.csdn.net/caroline_wendy/article/details/32159455 模板方法模式的一个主要的应用是排序(sort)算法. 对象的排列方式并不是完全相同, 所以需要排序(sort)算法compareTo()