Java设计模式—模板方法模式

1、介绍

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。

2、结构

①、模板方法模式结构可以分为两个角色:
      抽象模板(Abstract Template)角色
      具体模板(Concrete Template)角色
②、模板方法模式的静态结构图如下所示:


这里涉及到两个角色:
抽象模板(Abstract Template)角色职责:

  • 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。
  • 定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

具体模板(Concrete Template)角色职责:

  • 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。
  • 每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

3、代码示例

抽象模板角色类

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

/**
* 抽象模板类
*
* @author gulj
* @create 2017-09-08 下午2:48
**/
public abstract class AbstractTemplate {


/**
* 模板方法(定义模板的算法,整体骨架,业务方法由具体子类实现)
*
* @param params
* @return
*/
public final String templateMethod(String params) {//核心的模板方法,不允许子类覆盖
long startTime = System.currentTimeMillis();//模板方法,统一的模板


/**
* 具体的业务方法,可以有以下三种方式
*/

System.out.println("---------------------------");

// ①、需要所有子类实现各自的业务逻辑
String result = abstractMethod(params);

// ②、本类已经实现的方法
concreteMethod();

// ③、需要的子类可以重写
hookMethod();

System.out.println("---------------------------");


long endTime = System.currentTimeMillis();//模板方法,统一的模板
System.out.println("耗时时间:" + (endTime - startTime));
return result;
}


/**
* 抽象方法,供子类具体实现,定义为protected,可以只保证子类来实现,外界不允许调用
*
* @param params
* @return
*/
protected abstract String abstractMethod(String... params);


/**
* 基本方法(已经实现)
*/
private final String concreteMethod() {
System.out.println("concreteMethod : 模板类实现已经实现的放方法");
return null;
}


/**
* 基本方法(空方法)
*/
protected void hookMethod() {
/**
* 我们可以定义一个空方法,这样可以保证不是所有子类都需要重写该方法
*/
System.out.println("hookMethod : 模板类的空方法,可供某些子类进行重写");
}


}

具体模板角色类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/**
* 具体模板角色类
*
* @author gulj
* @create 2017-09-08 下午3:25
**/
public class ConcreteTemplate extends AbstractTemplate {

/**
* 重写父类的抽象方法
*
* @param params
* @return
*/
@Override
protected String abstractMethod(String... params) {
System.out.println("abstractMethod : 子类实现模板类中的抽象方法");
return null;
}
}

测试代码

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

/**
* @author gulj
* @create 2017-09-08 下午3:29
**/
public class TestTemplateDesignMain {


public static void main(String[] args) {
//子类实例
ConcreteTemplate concreteTemplate = new ConcreteTemplate();
//调用弗父类的模板方法
concreteTemplate.templateMethod("");

/**
* 测试结果
*

---------------------------
abstractMethod : 子类实现模板类中的抽象方法
concreteMethod : 模板类实现已经实现的放方法
hookMethod : 模板类的空方法,可供某些子类进行重写
---------------------------
耗时时间:1

*/
}
}

4、说明

模板方法中的方法可以分为两大类:模板方法和基本方法。

①、模板方法

一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。

一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。

②、基本方法

基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字标示。

具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换,如代码示例中的:concreteMethod()方法。

钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现,如代码示例中的:hookMethod()方法。