【图解设计模式】Template Method模式

在父类中定义处理流程的框架,在子类中实现具体处理。

组成模板的方法被定义在父类中。由于这些方法是抽象方法,所以只查看父类的代码是无法知道这些方法最终会进行何种具体处理的,唯一能知道的就是父类是如何调用这些方法的。

实现上述这些抽象方法的是子类。在子类中实现了抽象方法也就决定了具体的处理。也就是说,只要在不同的子类中实现不同的具体处理,当父类的模板方法被调用时程序行为也会不同。但是不论子类中的具体实现如何,处理的流程都会按照父类中所定义的那样进行。

示例

将字符和字符串循环显示5次。

类图

C5MmDO.png

AbstractDisplay类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class AbstractDisplay {
abstract void open();
abstract void print();
abstract void close();

final void display() {
open();

for (int i = 0; i < 5; i++)
print();

close();
}
}

CharDisplay类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CharDisplay extends AbstractDisplay {
private char ch;

public CharDisplay(char ch) {
this.ch = ch;
}

@Override
void open() {
System.out.print("<<");
}

@Override
void print() {
System.out.print(ch);
}

@Override
void close() {
System.out.println(">>");
}
}

StringDisplay类

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
public class StringDisplay extends AbstractDisplay {
private String string;
private int width;

public StringDisplay(String string) {
this.string = string;
this.width = string.getBytes().length;
}

@Override
void open() {
printLine();
}

@Override
void print() {
System.out.println("|" + string + "|");
}

@Override
void close() {
printLine();
}

private void printLine() {
System.out.print("+");

for (int i = 0; i < width; i++)
System.out.print("-");

System.out.println("+");
}
}

Main类

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {

public static void main(String[] args) {
AbstractDisplay d1 = new CharDisplay('H');
AbstractDisplay d2 = new StringDisplay("Hello, world.");
AbstractDisplay d3 = new StringDisplay("你好,世界。");

d1.display();
d2.display();
d3.display();
}
}

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<<HHHHH>>
+-------------+
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
+-------------+
+------------------+
|你好,世界。|
|你好,世界。|
|你好,世界。|
|你好,世界。|
|你好,世界。|
+------------------+

登场角色

AbstractClass(抽象类)

AbstractClass角色不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法。这些抽象方法由子类ConcreteClass角色负责实现。在示例程序中,由AbstractDisplay类扮演此角色。

ConcreteClass(具体类)

该角色负责具体实现AbstractClass角色中定义的抽象方法。这里实现的方法将会在AbstractClass角色的模板方法中被调用。在示例程序中,由CharDisplay类和StringDisplay类扮演此角色。

类图

C5QR6P.png