《HeadFirst设计模式》读书笔记-第8章-模板方法模式
来源:互联网 发布:网络系统集成课后答案 编辑:程序博客网 时间:2024/05/20 20:02
定义
模板方法模式(template method pattern)在一个方法中定义一个算法的骨架,而将一些步骤延时到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
下面给出了该类图的代码实现和说明:
public abstract class AbstractClass { /** * 这个是个模板方法 * 声明为final是为了防止子类覆盖,以免子类改变这个算法的顺序和结构 */ final void templateMethod() { primitiveOperation1(); primitiveOperation2(); concreteOperation(); hook(); } /** * 算法中的步骤,子类根据实际情况实现具体行为 */ abstract void primitiveOperation1(); abstract void primitiveOperation2(); /** * 算法中的步骤 * 声明为final是为了防止子类覆盖 */ final void concreteOperation() { // 这里是具体实现 } /** * 模板方法定义的钩子 * 钩子的存在让子类有能力在算法的一些重要时间点被通知,并可以去实现一些功能 * 子类根据需要决定是否实现钩子 */ void hook() { }}
模板方法中钩子和抽象方法的区分:
抽象方法是算法中不可缺少的,非常重要的步骤,子类必须实现。
钩子是可选的,子类自由选择是否实现。
钩子的存在有两个目的:
对算法中不重要的,可选的细节让子类进行实现
通知算法执行的时间节点的发生,类似回调函数
代码实现
我们看看JDK是如何用模板方法来实现数组的排序的。
首先给出需要排序的对象类型,实现Comparable接口:
public class Duck implements Comparable { String name; int weight; public Duck(String name, int weight) { this.name = name; this.weight = weight; } public String toString() { return name + " weighs " + weight; } // Comparable接口中的方法,定义了如何实现Duck对象的比较 public int compareTo(Object object) { Duck otherDuck = (Duck) object; if (this.weight < otherDuck.weight) { return -1; } else if (this.weight == otherDuck.weight) { return 0; } else { // this.weight > otherDuck.weight return 1; } }}
测试代码:
import java.util.ArrayList;import java.util.Arrays;public class DuckSortTestDrive { public static void main(String[] args) { Duck[] ducks = { new Duck("Daffy", 8), new Duck("Dewey", 2), new Duck("Howard", 7), new Duck("Louie", 2), new Duck("Donald", 10), new Duck("Huey", 2) }; Arrays.sort(ducks); }}
继续看Arrays的sort()方法的实现,会发现最终由下面代码片段实现排序:
/** * 排序dest[low:high]中的对象 * compareTo()方法正是我们Duck对象实现的方法, * swap()是由Arrays类实现的方法, */for (int i=low; i<high; i++) for (int j=i; j>low && ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--) swap(dest, j, j-1);
这个模板方法和我们类图中的不大一样,差别在于标准的模板方法是定义了一个算法的框架,有子类实现某些具体的步骤。而这里没有用到继承,这是因为Array类的sort()方法的设计者收到一些约束:
他希望sort()方法适用于所有的数组,而每个数组都是不同的类,所以无法设计一个类继承Java数组。
所以他把sort()方法定义成静态方法,由被排序的数组元素对象实现Comparable接口,实现对象的比较动作,这个比较的方式可能每个类不一样。swap()实现数组元素的交换,属于通用的方法,所以由Array类实现。
所以上面的描述,sort()方法的设计符合模板方法模式的核心思想:定义了一个算法的框架,有具体类实现某些具体的步骤。
本章金句
模板方法模式为我们提供了一种代码复用的重要技巧
真实世界中有很多模板方法模式的变体,不一定都是标准的,比如Array.sort()方法
策略模式和模板方法模式都是封装算法的,策略模式使用组合,模板方法模式使用的是继承
策略模式封装了完整的算法,模板方法只提供了算法的框架,需要具体类去实现某些步骤
工厂方法是模板方法的一种特殊版本,用于对象的创建
好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用底层模块
- 《HeadFirst设计模式》读书笔记-第8章-模板方法模式
- HeadFirst 设计模式 8模板方法模式
- HeadFirst设计模式_读书笔记_008_模板方法
- 《HeadFirst设计模式》读书笔记-第1章-策略模式
- 《HeadFirst设计模式》读书笔记-第2章-观察者模式
- 《HeadFirst设计模式》读书笔记-第4章-工厂模式
- 《HeadFirst设计模式》读书笔记-第5章-单例模式
- 《HeadFirst设计模式》读书笔记-第6章-命令模式
- 《HeadFirst设计模式》读书笔记-第3章-装饰者模式
- 《HeadFirst设计模式》读书笔记-第7章-外观模式
- 《HeadFirst设计模式》读书笔记-第7章-适配器模式
- 《HeadFirst设计模式》读书笔记-第9章-迭代器模式
- HeadFirst 设计模式学习笔记8--模板方法模式
- HeadFirst 设计模式学习笔记8--模板方法模式
- HeadFirst设计模式 读书笔记
- HeadFirst设计模式 读书笔记
- 读书笔记:《HeadFirst设计模式》
- HeadFirst设计模式读书笔记
- C#140课的主要内容
- HDOJ 1505 City Game (单调栈)
- tasklet机制和工作队列
- [hihocoder1490]Tree Restoration恢复树
- 第七章 循环控制
- 《HeadFirst设计模式》读书笔记-第8章-模板方法模式
- 编码与python中文使用问题
- android技术选型(持续更新中...)
- 利用自动索引计算数组元素的平方和
- MySQL存储过程详解
- 博客开篇
- 【腾讯云的1001种玩法】LAMP架构实现动态网站论坛系统
- io
- 关于this指向的理解