《Head First 设计模式》之模板方法模式——冲泡咖啡和茶

模板方法模式(Template)

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

好莱坞原则:别调用(打电话给)我们,我们会调用(打电话给)你。

要点:

1.模板方法的抽象类可以定义具体方法、抽象方法和钩子。抽象方法由子类实现。

2.钩子是一种方法,在抽象类中不做事,或只做默认的事,子类可以选择要不要覆盖它。

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

4.好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。

5.策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

6.工厂方法(由子类决定实例化哪个具体类)是模板方法(子类决定如何实现算法中的步骤)的一种特殊版本。

示例:

咖啡冲泡法

1.把水煮沸

2.用沸水冲泡咖啡

3.把咖啡倒进杯子

4.加糖和牛奶

茶冲泡法

1.把水煮沸

2.用沸水冲泡茶叶

3.把茶倒进杯子

4.加柠檬

茶和咖啡是如此得相似,似乎我们应该将共同的部分抽取出来,放进一个基类中。

1 public abstract class CaffeineBeverage {

2 // 现在,用同一个prepareRecipe()方法来处理茶和咖啡。

3 // prepareRecipe()方法被声明为final,因为我们不希望子类覆盖这个方法

4 // 我们将第2步和第4步泛化成为brew()和addCondiments()

5 final void prepareRecipe() {

6 boilWater();

7 brew();

8 pourInCup();

9 addCondiments();

10 }

11

12 // 因为咖啡和茶处理这些方法的做法不同,所以这两个方法必须被声明为抽象,

13 // 剩余的东西留给子类去操心

14 abstract void addCondiments();

15 abstract void brew();

16

17 public void boilWater() {

18 System.out.println("Boiling water");

19 }

20

21 public void pourInCup() {

22 System.out.println("Pouring into cup");

23 }

24 }

让我们细看抽象类是如何被定义的,包括了它内含的模板方法和原语操作。

1 public class Coffee extends CaffeineBeverage {

2 @Override

3 void brew() {

4 System.out.println("Dripping coffee through filter");

5 }

6

7 @Override

8 void addCondiments() {

9 System.out.println("Adding Sugar and Milk");

10 }

11 }

12

13 public class Tea extends CaffeineBeverage {

14 @Override

15 void brew() {

16 System.out.println("Steeping the tea");

17 }

18

19 @Override

20 void addCondiments() {

21 System.out.println("Adding Lemon");

22 }

23 }

钩子的使用

1 public abstract class CaffeineBeverageWithHook {

2 final void prepareRecipe() {

3 boilWater();

4 brew();

5 pourInCup();

6 // 我们加上了一个小小的条件语句,而该条件是否成立,

7 // 是由一个具体方法customerWantsCondiments()决定的。

8 // 如果顾客“想要”调料,只有这时我们才调用addCondiments()。

9 if (customerWantsCondiments()) {

10 addCondiments();

11 }

12 }

13

14 abstract void addCondiments();

15 abstract void brew();

16

17 public void boilWater() {

18 System.out.println("Boiling water");

19 }

20

21 public void pourInCup() {

22 System.out.println("Pouring into cup");

23 }

24

25 // 我们在这里定义了一个方法,(通常)是空的缺省实现。这个方法只会返回true,不做别的事。

26 // 这就是一个钩子,子类可以覆盖这个方法,但不见得一定要这么做。

27 boolean customerWantsCondiments() {

28 return true;

29 }

30 }

复制代码

用模板方法排序

Java数组类的设计者提供给我们一个方便的模板方法用来排序。必须实现Comparable接口,提供这个接口所声明的compareTo()方法。

其他模板方法实例

1.java.io的InputStream类有一个read()方法,是由子类实现的,而这个方法又会被read(byte b[], int off, int len)模板方法使用。

2.Swing的JFrame继承了一个paint()方法。在默认状态下,paint()是不做事情的,因为它是一个“钩子”。通过覆盖paint(),可以将自己的代码插入JFrame的算法中,显示出想要的画面。

3.applet是一个能在网页上面执行的小程序。任何applet必须继承自Applet类,而Applet类中提供了好些钩子。

www.cnblogs.com/-1307/p/6441182.html

咖啡泡JAVA_java《Head First 设计模式》之模板方法模式——冲泡咖啡和茶相关推荐

  1. 《Head First 设计模式》之模板方法模式——冲泡咖啡和茶

    模板方法模式(Template) --在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 好莱坞原则:别调用(打电话给 ...

  2. C++设计模式之模板方法模式

    模板方法模式 设计模式的定义 模板方法模式详解 背景----柠檬茶和咖啡的的冲泡方式 代码实现咖啡和茶冲泡的类 整理相似点 进一步设计 总结一下 认识模板方法 测试一下 模板方法模式的优点 模板方法的 ...

  3. 【Java】设计模式之模板方法模式

    - 好记性不如烂笔头,特将设计模式之模板方法模式记录在我的小仓库. 文章目录 什么是模板方法模式 案例 什么是模板方法模式 简而言之就是一套算法可以适用于多个类,则进行的步骤汇总,让子类别在不改变算法 ...

  4. 一篇博客读懂设计模式之---模板方法模式

    设计模式之模板方法模式: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 简而言之就是:父类定义了骨架(调用哪些方法及其 ...

  5. 设计模式之模板方法模式详解

    设计模式之模板方法模式详解 概述 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的 ...

  6. Java设计模式之模板方法模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  7. php templete什么意思,PHP设计模式之模板方法模式定义与用法详解

    本文实例讲述了PHP设计模式之模板方法模式定义与用法.分享给大家供大家参考,具体如下: 什么是模板方法模式 模板方法(Template Method)设计模式中使用了一个类方法templateMeth ...

  8. 【设计模式】模板方法模式(C#)

    [设计模式]模板方法模式 1.概述 背景 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某 ...

  9. 设计模式之模板方法模式(TemplateMethod)

    设计模式之模板方法模式 模板方法模式 代码实现 模式的应用 模板方法模式 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现 ...

最新文章

  1. [ZZ]Map/Reduce hadoop 细节
  2. HTML5培训后好就业吗
  3. 实验四十一、×××(IPSec)的配置
  4. Java DatagramSocket(UDP)要注意的问题
  5. SpringBoot(一)——快速入门
  6. 混淆视听的感脚(二)
  7. python语法笔记(五)
  8. pytorch梯度下降函数_Pytorch中常用的四种优化器SGD、Momentum、RMSProp、Adam
  9. php 重载进程,关于php-fpm与nginx进程重载
  10. At present, Huawei has two more important
  11. LIve Writer图片自动水印,自动居中,自动为原始大小的设置方法.
  12. android 接口的调用方法参数类型转换,Android NDK开发之JNI基础
  13. 软件工程 第四章 概要设计
  14. android 点击屏幕事件_Android 事件分发机制
  15. FPGA实现SPI 协议
  16. 【PMP】工作分解结构WBS详解
  17. Java 杨辉三角形
  18. 未来生活进行时: 畅想未来新兴技术40年——百大趋势性技术汇总(上)
  19. Android 图片文字识别
  20. Win11怎么以管理员身份运行?Win11以管理员身份运行的设置方法

热门文章

  1. java键盘输入构建任意二叉树并实现前序、中序、后续遍历
  2. 解决python画图中colorbar设置刻度和标签字体大小
  3. c++ OpenCV 读取某个文件夹下的所有图片
  4. mac下实现游戏多开
  5. cpu缓存一致性详解
  6. ppt编写一个抽奖系统
  7. 算法分析:锦标赛问题 分治算法
  8. vue路由传参的三种方式
  9. 纯CSS(基于CSS3)实现表格固定行列(附:样式与JS配置实现固定列行)
  10. Web程序设计—ASP.NET实用网站开发(第三版)课后习题答案