模板方法算是种较为常见的设计模式,同时对于大多数场景来说也很实用。在面临多算法交换更替使用的情况下,模板方法为你提供了各种算法的“开关”,提高算法的代码复用度。


  • 举例

不画类图了,直接上代码示例。

这是算法的模板抽象类,process*()是算法的每个步骤,execute()则是完整得执行算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class PublicExecute {
public int process1() {
return 0;
}
public void process2(int i) {
System.out.println("打印 >>>>> " + i);
}
public abstract void process3();
//执行算法
public void execute() {
process2(process1());
process3();
}
}

下面有两个继承PublicExecute并实现其抽象方法的实现类,补充了算法的完整性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//算法1
public class Execute1 extends PublicExecute {
@Override
public void process3() {
// TODO Auto-generated method stub
System.out.println("完成 >>>>> Execute1");
}
public void process2(int i) {
System.out.println("打印 >>>>> " + (i + 100));
}
}
//算法2
public class Execute2 extends PublicExecute {
@Override
public void process3() {
// TODO Auto-generated method stub
System.out.println("完成 >>>>> Execute2");
}
}

上述代码可见,Execute1实现了process3(),也同时重写process2(int i)Execute2仅仅实现了process3()

代码跑起!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* 我觉得模板方法应该不难看懂,说白了就是重写算法每个步骤的实现方法。
*/
public class TemplateMethod {
public static void main(String[] args) {
PublicExecute execute1 = new Execute1();
PublicExecute execute2 = new Execute2();
/*
* 打印 >>>>> 100
* 完成 >>>>> Execute1
*/
execute1.execute();
/*
* 打印 >>>>> 0
* 完成 >>>>> Execute2
*/
//execute2.execute();
}
}

  • JDK中的模板方法模式

jdk可谓是设计模式之集大成,肯定少不了模板方法的。

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Arrays {
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a);
}
/** To be removed in a future release. */
private static void legacyMergeSort(Object[] a) {
Object[] aux = a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
/**
* Src is the source array that starts at index 0
* Dest is the (possibly larger) array destination with a possible offset
* low is the index in dest to start sorting
* high is the end index in dest to end sorting
* off is the offset to generate corresponding low, high in src
* To be removed in a future release.
*/
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
// Insertion sort on smallest arrays
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;
}
/*
* 略
*/
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
}

JDK中java.util.Arrayssort方法就是典型的模版方法,而从私有方法mergeSort来看,为我们提供算法修改的方法则是ObjectcompareTo

  • 写个compareTo的例子

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
class Dick implements Comparable<Dick> {
private String name;
private int size;
public Dick(String name, int size) {
super();
this.name = name;
this.size = size;
}
@Override
public String toString() {
return "Dick [name=" + name + ", size=" + size + "cm]";
}
// 实现Comparable接口
@Override
public int compareTo(Dick o) {
// TODO Auto-generated method stub
if(this.size == o.getSize())
return 0;
else if(this.size >= o.getSize())
return 1;
else
return -1;
}
}

测试、打印.

1
2
3
4
5
6
7
8
9
10
11
12
public class TestArraysSort {
public static void main(String[] args) {
Dick[] fuckers = {new Dick("张三", 17),
new Dick("李四", 14),
new Dick("王五", 29),
new Dick("老六", 22),
new Dick("赵七", 11)};
Arrays.sort(fuckers);
for(Dick fucker : fuckers)
System.out.println(fucker);
}
}

结果:

1
2
3
4
5
Dick [name=赵七, size=11cm]
Dick [name=李四, size=14cm]
Dick [name=张三, size=17cm]
Dick [name=老六, size=22cm]
Dick [name=王五, size=29cm]