一. 前言

1. 定义

TemplateMethod:定义一个模板结构,将具体内容延迟到子类去实现。

2. 主要作用

在不改变模板结构的前提下在子类中重新定义模板中的内容。

注意:模板方法模式是基于 继承 的。

3. 解决的问题

① 提高代码复用性:将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

② 实现了反向控制:通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合 开闭原则。

二. 实际例子

1. 概况

背景:小成希望学炒菜:辣椒炒包菜 & 蒜蓉炒菜心。

炒菜的步骤:倒油 -> 热油 -> 放蔬菜 -> 放调味品 -> 翻炒。

2. 代码

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
public class MyClass {
/**
* 模板类:用来控制炒菜的流程
*/
public static abstract class CookClass{
//炒菜
//声明为final 不希望子类覆盖这个方法,放置更改流程的执行顺序
public final void cook(){
//第一步:倒油
this.pourOil();
//第二步:热油
this.heatOil();
//第三步:放蔬菜
this.pourVegetable();
//第四布:放调味品
this.pourSauce();
//第五步:翻炒
this.fry();
}

//倒油
public void pourOil(){
System.out.println("倒油");
}

//热油
public void heatOil(){
System.out.println("热油");
}

//放蔬菜
public abstract void pourVegetable();

//放调味瓶
public abstract void pourSauce();

//翻炒
public void fry(){
System.out.println("翻炒");
}
}

/**
* 制作包菜炒辣椒
*/
public static class CookBaoCai extends CookClass{

@Override
public void pourVegetable() {
System.out.println("放入的蔬菜是:包菜");
}

@Override
public void pourSauce() {
System.out.println("放入的调料是:辣椒");
}
}

/**
* 制作蒜蓉炒菜心
*/
public static class CookCaiXin extends CookClass{

@Override
public void pourVegetable() {
System.out.println("放入的蔬菜是:菜心");
}

@Override
public void pourSauce() {
System.out.println("放入的调料是:蒜蓉");
}
}

/**
* 测试
*/
public static void main(String[] args) {
//制作辣椒炒包菜
System.out.println("1.制作辣椒炒包菜");
new CookBaoCai().cook();

System.out.println();

//制作蒜蓉炒菜心
System.out.println("2.制作蒜蓉炒菜心");
new CookCaiXin().cook();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//运行结果
1.制作辣椒炒包菜
倒油
热油
放入的蔬菜是:包菜
放入的调料是:辣椒
翻炒

2.制作蒜蓉菜心
倒油
热油
放入的蔬菜是:菜心
放入的调料是:蒜蓉
翻炒

三. 优缺点以及应用场景

1. 优点

  • 提高代码复用性:将相同部分的代码放在抽象的父类中。

  • 提高了拓展性:将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为。

  • 实现了反向控制:通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,实现了反向控制 & 符合 开闭原则。

2. 缺点

引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。

3. 应用场景

  • 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
  • 控制子类的扩展。

参考文章

模板方法模式(Template Method) - 最易懂的设计模式解析