一 类别

​ 行为型模式

二 概述

​ 定义一个操作的基本框架,框架中的方法有基本方法和模版方法。模版方法是对基本方法的组装与调用,从而完成固定的逻辑,基本方法是其他子类对接口实现的重载,从而使用相同的模版,产生不同的结果。

三 使用场景

​ A. 多个子类有共有的方法,并且逻辑基本相同;

​ B. 很多依赖与某一核心算法,可以将该算法设为模版算法;

​ C. 重构中对于重复业务逻辑的代码通过设置模版方法如钩子函数、装饰器进行设计;

四 优点

​ A. 将共有的部分进行封装、减少代码的重复性,以便于系统的高可维护性。

​ B. 基本方法的实现延迟到子类进行具体实现,控制的行为由父类约束。

五 实现

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
package Template

import "fmt"

/*
@Time : 2021/1/12 13:25
@Author : austsxk
@Email : austsxk@163.com
@File : template.go
@Software: GoLand
*/

// 定义一个基类接口,该接口包含了一系列相关的操作
type WorkInterface interface {
GetUp()
Working()
Sleep()
}

// 定义一个工作者的接口,每个工作者都有这些基本操作,然后将具体的实现交给子类
type Worker struct {
WorkInterface
}

// 定义一个工作者的日常行为
func (w *Worker) Daily() {
w.GetUp()
w.Working()
w.Sleep()
}

// 任何实现了WorkInterface的子类,都可以传入到其中,然后调用其日常方法,就能实现子类的三个具体实现,即多态的实现
func NewWorker(w WorkInterface) *Worker {
return &Worker{w}
}

// 定义一个清洁员类
type EnvironmentalSanitationWorker struct {
}

func (e *EnvironmentalSanitationWorker) GetUp() {
fmt.Println("环卫阿姨起床了...")
}

func (e *EnvironmentalSanitationWorker) Working() {
fmt.Println("环卫阿姨正在打扫卫生...")
}

func (e *EnvironmentalSanitationWorker) Sleep() {
fmt.Println("环卫阿姨要休息了...")
}

// 定义一个程序员类
type Programmer struct {
}

func (e *Programmer) GetUp() {
fmt.Println("程序员起床了...")
}

func (e *Programmer) Working() {
fmt.Println("程序员正在疯狂敲代码...")
}

func (e *Programmer) Sleep() {
fmt.Println("程序员睡觉了...")
}

测试:

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
package Template

import "testing"

/*
@Time : 2021/1/12 18:14
@Author : austsxk
@Email : austsxk@163.com
@File : template_test.go
@Software: GoLand
*/

func TestNewWorker(t *testing.T) {
ewer := NewWorker(&EnvironmentalSanitationWorker{})
ewer.Daily()
programmer := NewWorker(&Programmer{})
programmer.Daily()
}

// go test -v template.go template_test.go

/*
test result:
=== RUN TestNewWorker
环卫阿姨起床了...
环卫阿姨正在打扫卫生...
环卫阿姨要休息了...
程序员起床了...
程序员正在疯狂敲代码...
程序员睡觉了...
--- PASS: TestNewWorker (0.00s)
PASS
ok command-line-arguments 0.647s
*/

说明: WorkInterface 接口抽象出一系列基本方法如GetUp、Working、Sleep,这些方法的具体实现延迟到由各个子类中;Worker 嵌入该接口,也就意味着,可以对该接口的方法进行组装和逻辑控制,即抽象的父类。在这个结构体中,有一个指针方法为Daily日常,就是模版方法,通过调用基本方法从而实现控制逻辑。然后通过实例化Worker对象时,将实现了WorkInterface接口的任何对象传入,就可以实现相同业务的控制,与分别各自实现相同方法而言,消除了重复的代码量。