`
jgsj
  • 浏览: 962288 次
文章分类
社区版块
存档分类
最新评论

设计模式笔记08-模板方法模式

 
阅读更多

设计模式笔记08-模板方法模式


1 引言


直到目前,我们的议题都绕着封装转,我们已经封装了对象创建、方法调用、复杂接口、鸭子、披萨。接下来呢?我们将要深入封装算法块,好让子类可以在任何时候都可以将自己挂接进运算里。我们甚至会在本章学到一个受到好莱坞影响而启发的设计原则。

2 正文


2.1 多来点咖啡因吧


有些人没有咖啡就活不下去,有些人则离不开茶。两者的共同成分是什么,当然是咖啡因啦。
让我们扮演“代码师傅“,写一些代码来创建咖啡和茶。
下面是咖啡:

public class Coffee {
 
	/*
	 * 这是我们的咖啡冲泡方法,直接取自训练手册。
	 * 每个步骤都被实现在分离的方法中。
	 * 这里每个方法都实现了算法中的一个步骤:煮沸水、冲泡咖啡、把咖啡倒进杯子、加糖和加奶。
	 */
	void prepareRecipe() {
		boilWater();
		brewCoffeeGrinds();
		pourInCup();
		addSugarAndMilk();
	}
 
	public void boilWater() {
		System.out.println("Boiling water");
	}
 
	public void brewCoffeeGrinds() {
		System.out.println("Dripping Coffee through filter");
	}
 
	public void pourInCup() {
		System.out.println("Pouring into cup");
	}
 
	public void addSugarAndMilk() {
		System.out.println("Adding Sugar and Milk");
	}
}

下面是茶

public class Tea {
 
	/*
	 * 这看起来和前一页的咖啡的实现很像,其中第2和第4个步骤不一样,但基本上是相同的冲泡法。
	 */
	void prepareRecipe() {
		boilWater();
		steepTeaBag();
		pourInCup();
		addLemon();
	}
 
	public void boilWater() {
		System.out.println("Boiling water");
	}
 
	public void steepTeaBag() {
		System.out.println("Steeping the tea");
	}
 
	public void addLemon() {
		System.out.println("Adding Lemon");
	}
 
	public void pourInCup() {
		System.out.println("Pouring into cup");
	}
}

我们发现了重复的代码,这是好现象。这表示我们需要清理一下设计了。在这里,既然茶和咖啡是如此的相似,似乎我们应该将共同的部分抽出来,放进一个基类中。

现在我们有了新的prepareRecipe()方法,但是需要让它能够符合代码。要想这么做,我们先从CaffeineBeverage(咖啡因饮料:茶和咖啡)超类开始。

public abstract class CaffeineBeverage {
	
	/*
	 * 现在,用同一个prepareRecipe()方法来处理茶和咖啡。
	 * prepareRecipe()被声明为final,因为我们不希望子类覆盖这个方法。
	 * 我们将步骤2和步骤4泛化为brew()和addCondiments()方法。
	 */
	final void prepareRecipe() {
		boilWater();
		brew();
		pourInCup();
		addCondiments();
	}
 
	/*
	 * 因为咖啡和茶处理这些方法的做法不同,所以这两个方法必须被声明为抽象,由子类来实现具体方法。
	 */
	abstract void brew();
  
	abstract void addCondiments();
 
	void boilWater() {
		System.out.println("Boiling water");
	}
  
	void pourInCup() {
		System.out.println("Pouring into cup");
	}
}

最后,我们需要处理咖啡和茶类了。这两个类现在都是依赖超类(咖啡因饮料)来处理冲泡法,所以只需要自行处理冲泡和添加调料部分。

2.2 认识模板方法


prepareRecipe()是我们的模板方法。为什么?
因为:
1、毕竟它是一个方法。
2、它用作一个算法的模板,在这个例子中,算法是用来制作咖啡因饮料的。
在这个模板中,算法内的每一个步骤都被一个方法代表了。某些方法是由这个类(超类)来处理的,某些方法则是由子类来处理。

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

2.3 对模板方法进行挂钩


钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。
钩子有好几种用途,让我们先看其中一个,稍后再看其他几个:

public abstract class CaffeineBeverageWithHook {
 
	/*
	 * 我们加上了一个小小的条件语句,而该条件是否成立,是由一个具体方法customerWantsCondiments()决定的。
	 * 如果顾客“想要”调料,只有这时我们才调用addCondiments()。
	 */
	void prepareRecipe() {
		boilWater();
		brew();
		pourInCup();
		if (customerWantsCondiments()) {
			addCondiments();
		}
	}
 
	abstract void brew();
 
	abstract void addCondiments();
 
	void boilWater() {
		System.out.println("Boiling water");
	}
 
	void pourInCup() {
		System.out.println("Pouring into cup");
	}
 
	/*
	 * 我们再这里定义了一个方法,(通常)是空的缺省实现。这个方法只会返回true,不做别的事情。
	 * 这就是钩子,子类可以覆盖这个方法,但不见得一定要这么做。
	 */
	boolean customerWantsCondiments() {
		return true;
	}
}

2.4 好莱坞原则


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

好莱坞原则可以给我们一种防止“依赖“的方法。当高层组件依赖低层组件,而低层组件又依赖高层组件,而高层组件又依赖边侧组件,依赖就发生了。在这种情况下,没有人可以轻易地搞定系统是如何设计的。
在好莱坞原则之下,我们允许低层组件讲自己挂钩到系统上,但是高层组件决定什么时候和怎么样使用这些低层组件。换句话说,高层组件对待低层组件的方式是”别调用我们,我们会调用你“。

2.5 用模板方法来排序


实现compareTo()方法即可。


3 本章小结


模板方法从字面意思就很好理解,把握住新学的好莱坞原则,避免依赖,这个就是本章的精髓。


分享到:
评论

相关推荐

    C++设计模式笔记(03-01) – Template Method_模板方法(上)

    C++设计模式笔记(03-02) – Template Method_模板方法(下): https://blog.csdn.net/mofan6930/article/details/104383750 参考书籍:《设计模式:可复用面向对象软件的基础》 参考课程:《C++设计模式》-李建忠 ...

    23种设计模式学习笔记及源码

    23种设计模式学习笔记及源码,全部原创 欢迎提出意见和建议

    设计模式笔记(包含所有设计模式)个人总结提炼笔记

    设计模式是一种解决软件设计问题的经验总结,是在软件开发过程中经过反复验证的最佳实践。设计模式提供了一套通用的解决方案,可以帮助开发人员更好地组织和设计代码,提高代码的可读性、可维护性和可扩展性。 设计...

    设计模式笔记总结 含C#示例代码 复习好帮手

    设计模式笔记总结 含C#示例代码 复习好帮手 总结了19中经典模式 每章包括 模式概念 角色与结构 代码示例 个人整理排版 pdf格式 排版精美 想当年我们班考试都是用我这个复习的

    设计模式经典样例笔记与代码Swift.zip

    设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...

    如何打造赢得用户的产品服务与商业模式《创新设计》读书笔记ppt模板.rar

    产品设计是用户与产品间的直接情感联系,无论好坏,从汽车到烤面包机,产品设计是对产品质量和性能的诠释,本书作者认为真正的创新是增加用户使用和体验价值,并详细阐述了如何在设计...《创新设计》读书笔记ppt模板。

    软件设计模式经典案例讲解

    针对几种经典软件设计模式:模板方法模式 外观模式 代理模式 装饰器模式 桥模式 工厂方法模式 组合模式等给出了简单易懂的讲解,透彻明了。很好的学习资料哦,是我平时学习时做的笔记外加自己的理解,很不错的……

    JAVA23种设计模式及快捷记忆

    设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。工厂模式、抽象工厂模式、...

    如何打造赢得用户的产品服务与商业模式《创新设计》读书笔记PPT模板.pptx

    如何打造赢得用户的产品服务与商业模式《创新设计》读书笔记PPT模板.pptx

    笔记-4、显式锁和AQS(1)1

    学习它的必要性AQS使用方式和其中的设计模式继承,模板方法设计模式了解其中的方法模板方法:独占式获取accquireacquireInterruptiblytr

    java-design-patterns:Java 设计模式学习笔记

    Java Design PatternsJava 设计模式学习笔记,简单易懂,每个模式都有相应的代码示列,帮助学习理解。在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式...

    观看韩顺平学习整理java的笔记到异常

    抽象类--模板设计模式 9 接口 9 内部类 11 匿名内部类的使用(重要!!!!!!!) 13 成员内部类的使用 13 静态内部类的使用 14 枚举的二种实现方式 14 自定义类实现枚举 14 使用 enum 关键字实现枚举注意事项 15 enum 用...

    Java面向对象程序设计笔记

    模板模式: 16 组合设计模式: 16 9. 多态 16 10. 内部类 17 第五章 Java集合对象 18 1.List 18 2.Set 18 3.Map 19 第六章 常用的API类 21 1.对文件进行操作的类 21 2.对String对象操作的类 ...

    稳稳当当学java之设计模式(12).md

    本人的笔记,关于java基础中设计模式的内容 包括 1.作业回顾 2.内部类 2.1局部内部类 2.2静态内部类 2.3匿名内部类 3.设计模式 3.1单例模式 3.2代理模式 3.3观察者模式 3.4模板模式 4.练习

    cad-笔记本图纸

    CAD系统的发展和应用使传统的产品设计方法与生产模式发生了深刻的变化,产生了巨大的社会经济效益。目前CAD技术研究热点有计算机辅助概念设计、计算机支持的协同设计、海量信息存储、管理及检索、设计法研究及其相关...

    asp.net知识库

    动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个时间转换的问题,顺便谈谈搜索技巧 .net中的正则表达式使用高级技巧 (一) C#静态成员和...

    java-patterns:Java 23种基本的设计模式整料整理学习,责任链模式过滤器,工厂模式BeanFactory,观察者模式ContextListen等。结合Spring源码理解学习

    describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...

    左程云leetcode-hjLearningNotes:hj学习笔记

    第一部分:设计模式 & UML 简单工厂 工厂方法模式 抽象工厂模式 策略模式 责任链模式 命令模式 模板方法模式 适配器模式 代理模式 外观模式 组合模式 装饰模式 享元模式 桥接模式 Builder模式 状态模式 解释器模式 ...

    《从零开始学架构》精华读书笔记

    《从零开始学架构》这本书的内容主要包含以下几部分:1) 架构设计基础,包括架构设计相关概念、历史、原则、基本方法,让架构设计不再神秘;2) 架构设计流程,通过一个虚拟的案例,描述了一个通用的架构设计流程,...

    leetcode下载-LearningNotes:学习笔记

    模板方法模式 访问者模式 中介者模式 组合模式 装饰模式 享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四...

Global site tag (gtag.js) - Google Analytics