Head First 设计模式笔记(模版方法模式)
1.定义:
在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
2.类图:

3.说明:
- 模版方法可以理解为一个方法里面包含了多个步骤的方法。该方法一般声明为final,防止被子类覆盖,保护了算法结构。
- 模版模式的“钩子方法”,允许通过钩子方法改名算法模版中的某些逻辑。
- 使用模版方法模式时,基类里面的方法是否都需要定义为抽象方法?这样子子类是否必须覆盖过多的方法。这点是需要根据实际情况考虑的。如果算法步骤切割的太细,会导致子类需要覆盖过多的方法(挺讨厌的),如果切割的不够细又会导致框架缺乏弹性。
- 好莱坞原则:别调用(找)我们,我们调用(找)你。目的在于解耦。
- 真实环境里学会选择周围的设计模式,同时也要识别设计模式的变体。例如jdk里面的Array类的sort排序方法就不是一个变体。
- 例子Arrays类的sort排序方法,InputStream类的read方法,JFrame类的paint方法
4.例子:Arras的排序方法,根据鸭子重量排序的例子
4.1Duck.java:
package com.test.design.template5;
//鸭子类。实现Comparable接口,需要覆盖一个compareTo的方法。
public class Duck implements Comparable<Object> {
private String name;
private int weight;
public Duck() {
// TODO Auto-generated constructor stub
}
public Duck(String name,int weight) {
this.name = name;
this.weight = weight;
}
@Override
public String toString() {
return name + ";" + weight;
}
@Override
public int compareTo(Object o) {
/*if(null == o) {
throw new Exception("");
}*/
Duck duck = (Duck)o;
if(this.weight < duck.weight) {
return -1;
} else if(this.weight == duck.weight) {
return 0;
} else {
return 1;
}
}
}
4.2TestDuck.java
package com.test.design.template5; import java.util.Arrays; //测试类
public class TestDuck {
public static void main(String[] args) {
Duck d1 = new Duck("鸭子1",11);
Duck d2 = new Duck("鸭子2",11);
Duck d3 = new Duck("鸭子3",13);
Duck d4 = new Duck("鸭子4",9);
Duck[] ducks = new Duck[4];
ducks[0] = d1;
ducks[1] = d2;
ducks[2] = d3;
ducks[3] = d4;
Arrays.sort(ducks);
for (int i = 0; i < ducks.length; i++) {
System.out.println(ducks[i].toString());
}
}
}
//输出结果:
鸭子4;9
鸭子1;11
鸭子2;11
鸭子3;13,排序正确。
如果我们看jdk中类Arrays类的sort(Object[] a)方法,会发现我们可以把sort(Object[] a)看作是一个模版方法,在里面调用了方法mergeSort(),在mergeSort方法里面传入了待排序的数组引用,同时在方法里面实现了排序。
待排序的数组自己覆盖了compareTo方法,所以具体根据什么排序是由待排序数组对象自己去实现的。根据compareTo的结果去判断是否调换数组元素的位置。直至所有的数组元素都根据定义好的规则排好序。
很明显,这不是“教科书式”的模版方法模式的例子。教科书式的模版方法模式,是定义一个抽象类,抽象类里面提供一个final的模版方法,在模版方法里面调用一系列的方法步骤,并且把需要子类去实现的步骤定义为抽象方法,让子类根据情况去具体实现。
jdk的作者希望Arrays提供一个静态方法,任何的对象数组都可以进行排序。于是定义了一个静态的sort方法,而被排序的对象内的每个元素自行提供比较大小的算法部分。虽然不是正宗的模版方法模式,但是却符合模版方法模式的精神。
//排序
public static void sort(Object[] a) {
Object[] aux = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
//排序
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
...
if (length < INSERTIONSORT_THRESHOLD) {
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);
return;
}
...
}
5.总结 :
要了解什么情况使用这个模式。
能够在以后看框架代码的时候发现学过的模式。
能够识别该模式的变体。
Head First 设计模式笔记(模版方法模式)的更多相关文章
- 设计模式 笔记 模版方法模式 Template Method
//---------------------------15/04/28---------------------------- //TemplateMethod 模版方法模式----类行为型模式 ...
- JS常用的设计模式(10)——模版方法模式
模式方法是预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现.听起来有点像工厂模式( 非前面说过的简单工厂模式 ). 最大的区别是,工厂模式的意图是根据子类的实现最 ...
- 设计模式之模版方法模式(Template Method Pattern)
一.什么是模版方法模式? 首先,模版方法模式是用来封装算法骨架的,也就是算法流程 既然被称为模版,那么它肯定允许扩展类套用这个模版,为了应对变化,那么它也一定允许扩展类做一些改变 事实就是这样,模版方 ...
- JAVA设计模式之模版方法模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述模板方法(Template Method)模式的: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式 ...
- java设计模式之模版方法模式以及在java中作用
模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有 ...
- [Head First设计模式]云南米线馆中的设计模式——模版方法模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- NET设计模式 第二部分 行为型模式(15):模版方法模式(Template Method)
摘要:Template Method模式是比较简单的设计模式之一,但它却是代码复用的一项基本的技术,在类库中尤其重要. 主要内容 1.概述 2.Template Method解说 3..NET中的Te ...
- 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)
. 实例介绍 在本例中,我们使用一个常见的场景,我们每个人都上了很多年学,中学大学硕士,有的人天生就是个天才,中学毕业就会微积分,因此得了诺贝尔数学奖:也有的人在大学里学了很多东西,过得很充实很满意 ...
- 【pattern】设计模式(2) - 模版方法模式
前言 一晃一年又过了,还是一样的渣. 一晃2周又过去了,还是没有坚持写博客. 本来前2天说填一下SQL注入攻击的坑,结果看下去发现还是ojdbc.jar中的代码,看不懂啊.这坑暂时填不动,强迫在元旦最 ...
随机推荐
- 安装postman工具模拟请求
扩展工具->: 注意,在创建快捷方式后,第一次打开这个工具,会让你注册信息,忽略它.关闭,重新打开postman工具,然后如下所示:
- 格式化字符串攻击原理及示例.RP
格式化字符串攻击原理及示例 一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的 ...
- JS 求解时间差
function UTCTimeDemo($str){ var d, s = "当前 UTC 时间为: "; var c = ":"; d = new Date ...
- ServletContext接口(六)
javax.servlet.ServletContext接口 ServletContext(上下文)是公用的,就是.net中的application,主要用到的就是全局set设置值,get获取值,ja ...
- java基础之转义符、数据类型
一. 转义符 1.\n \n的作用是换行,也就是和键盘上的回车键相同 2.\t \t的作用是制表,就是以八个空格为一个单位,当不足八个时会自动补齐八个,如asd\tfgh,那么输出的将会是 . 3. ...
- Centos7 调整磁盘空间
1. 查看磁盘空间占用情况: df -h 可以看到 /home 有很多剩余空间, 而节点较少. 2. 备份 /home 下的内容: cp -r /home/ homebak/ 3. 关闭home进程 ...
- Java整体之JavaEE
思维导图 (Xmind)链接:http://pan.baidu.com/s/1pKTOTRH 密码:oq7f <iframe src="http://www.xmind.net/emb ...
- 洛谷P3604 美好的每一天(莫队)
传送门 由乃的题还是一如既往的可怕…… 先放上原题解 标解: 一个区间可以重排成为回文串,即区间中最多有一个字母出现奇数次,其他的都出现偶数次 发现这个和 类似 这样如果一个区间的 和为 或者 ...
- 数据结构14:队列(Queue),“先进先出”的数据结构
队列是线性表的一种,在操作数据元素时,和栈一样,有自己的规则:使用队列存取数据元素时,数据元素只能从表的一端进入队列,另一端出队列,如图1. 图1 队列示意图 称进入队列的一端为“队尾”:出队列的一端 ...
- Python中使用Beautiful Soup库的超详细教程
[参考文献] http://www.jb51.net/article/65287.htm