模板方法模式 定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Template Method Pattern Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
类图
模式的结构与使用 模板方法方法模式的结构中包括两种角色。
抽象模板(Abstract Template):抽象模板是一个抽象类。抽象模板定义了若干个方法以表示一个算法的各个步骤,这些方法中有抽象方法也有非抽象方法,其中的抽象方法称作原语操作(Primitive Operation)。重要的一点是,抽象模板中还定义了一个称作模板方法的方法,该方法不仅包含有抽象模板中表示算法步骤的方法调用,而且也可以包含有定义在抽象模板中的其他对象的方法调用,即模板方法定义了算法的骨架。
具体模板(Concrete Template):具体模板是抽象模板的子类,实现抽象模板中的原语操作。
简单的例子 Abstract Template的抽象类AbstractTemplate.java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package TemplateMethod;
import java.io.File;
public abstract class AbstractTemplate {
File[] allFiles;
File dir;
public AbstractTemplate (File dir) {
this .dir = dir;
}
public final void showFileName () {
allFiles = dir.listFiles();
sort();
printFiles();
}
public abstract void sort () ;
public abstract void printFiles () ;
}
Abstract Template的实现类ConcreteTemplate1.java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package TemplateMethod;
import java.io.File;
import java.sql.Date;
import java.text.SimpleDateFormat;
public class ConcreteTemplate1 extends AbstractTemplate {
public ConcreteTemplate1 (File dir) {
super (dir);
}
@Override
public void sort () {
for (int i = 0 ; i < allFiles.length; i++) {
for (int j = i + 1 ; j < allFiles.length; j++) {
if (allFiles[j].lastModified() < allFiles[i].lastModified()) {
File file = allFiles[j];
allFiles[j] = allFiles[i];
allFiles[i] = file;
}
}
}
}
@Override
public void printFiles () {
for (int i = 0 ; i < allFiles.length; i++) {
long time = allFiles[i].lastModified();
Date date = new Date(time);
SimpleDateFormat matter = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss" );
String str = matter.format(date);
String name = allFiles[i].getName();
int k = i + 1 ;
System.out.println(k + " " + name + "(" + str + ")" );
}
}
}
Abstract Template的实现类ConcreteTemplate2.java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package TemplateMethod;
import java.io.File;
public class ConcreteTemplate2 extends AbstractTemplate {
public ConcreteTemplate2 (File dir) {
super (dir);
}
@Override
public void sort () {
for (int i = 0 ; i < allFiles.length; i++) {
for (int j = i + 1 ; j < allFiles.length; j++) {
if (allFiles[j].lastModified() < allFiles[i].lastModified()) {
File file = allFiles[j];
allFiles[j] = allFiles[i];
allFiles[i] = file;
}
}
}
}
@Override
public void printFiles () {
for (int i = 0 ; i < allFiles.length; i++) {
long fileSize = allFiles[i].length();
String name = allFiles[i].getName();
int k = i + 1 ;
System.out.println(k + " " + name + "(" + fileSize + "字节)" );
}
}
}
测试类Application.java 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package TemplateMethod;
import java.io.File;
public class Application {
public static void main (String[] args) {
File dir = new File("d:/java/masm5" );
AbstractTemplate template = new ConcreteTemplate1(dir);
System.out.println(dir.getPath() + "目录下的文件:" );
template.showFileName();
template = new ConcreteTemplate2(dir);
System.out.println(dir.getPath() + "目录下的文件:" );
template.showFileName();
}
}
执行效果图
电脑目录下文件截图
钩子方法 有时间一定补,不过下面优点介绍了一点钩子的好处
模板方法模式的优点
可以通过在抽象模板定义模板方法给出成熟的算法步骤,同时又不限制步骤的细节,具体模板实现算法细节不会改变整个算法的骨架。
在抽象模板模式中,可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤。
适用模板方法模式的情景
设计者需要给出一个算法的固定步骤,并将某些步骤的具体实现留给子类来实现。
需要对代码进行重构,将各个子类公共行为提取出来集中到一个共同的父类中以避免代码重复。
下载源码请到 MyGitHub