【笔记】Go语言设计模式的行为型模式

前言

Go语言设计模式的行为型模式学习笔记

职责链模式

  • 在该模式里,很多对象由每一个对象及其下家的引用而连接起来形成一条链,请求在这个链上传递,直到链上的某一个对象决定处理此请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配指责

命令模式

  • 将一个请求封装为一个对象,从而可以用不同的请求对客户端进行参数化、对请求排队、记录请求日志、支持可撤销的操作
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
package main

// Doctor 医生
type Doctor struct {
}

// 治疗眼睛
func (Doctor) treatEye() {}

// 治疗鼻子
func (Doctor) treatNose() {}

// TreatEyeList 治疗眼睛的病单
type TreatEyeList struct {
doctor *Doctor
}

// 治疗眼睛
func (treatEyeList TreatEyeList) treat() {
treatEyeList.doctor.treatEye()
}

// TreatNoseList 治疗鼻子的病单
type TreatNoseList struct {
doctor *Doctor
}

// 治疗鼻子
func (treatNoseList TreatNoseList) treat() {
treatNoseList.doctor.treatNose()
}

func main() {
// 创建医生
var doctor = new(Doctor)

// 治疗眼睛
var treatEyeList = TreatEyeList{doctor: doctor}
treatEyeList.treat()

// 治疗鼻子
var treatNoseList = TreatNoseList{doctor: doctor}
treatNoseList.treat()
}
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
package main

// Doctor 医生
type Doctor struct {
}

// 治疗眼睛
func (Doctor) treatEye() {}

// 治疗鼻子
func (Doctor) treatNose() {}

// TreatList 病单接口
type TreatList interface {
Treat()
}

// TreatEyeList 治疗眼睛的病单
type TreatEyeList struct {
doctor *Doctor
}

// Treat 治疗眼睛
func (treatEyeList TreatEyeList) Treat() {
treatEyeList.doctor.treatEye()
}

// TreatNoseList 治疗鼻子的病单
type TreatNoseList struct {
doctor *Doctor
}

// Treat 治疗鼻子
func (treatNoseList TreatNoseList) Treat() {
treatNoseList.doctor.treatNose()
}

// Nurse 护士
type Nurse struct {
treatNoseListList []TreatList
}

// Notify 发送病单给医生
func (nurse *Nurse) Notify() {
if nurse.treatNoseListList == nil {
return
}

// 发送病单
for _, treatNoseList := range nurse.treatNoseListList {
treatNoseList.Treat()
}
}

// 病人
func main() {
// 创建医生
var doctor = new(Doctor)
// 治疗眼睛病单
var treatEyeList = TreatEyeList{doctor: doctor}
// 治疗鼻子病单
var treatNoseList = TreatNoseList{doctor: doctor}

// 创建护士
var nurse = Nurse{treatNoseListList: make([]TreatList, 0)}
// 收集治疗眼睛病单
nurse.treatNoseListList = append(nurse.treatNoseListList, treatEyeList)
// 收集治疗鼻子病单
nurse.treatNoseListList = append(nurse.treatNoseListList, treatNoseList)

// 护士将病单交给医生
nurse.Notify()
}

解释器模式

  • 为简单的语言定义一个语法,在该语言中表示一个句子并解释这些句子

迭代器模式

  • 提供了一种方法顺序来访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示

中介者模式

  • 定义一个中介对象来封装系列对象之间的交互,中介者使各个对象不需要显式的相互调用,从而使其耦合性松散,而且可以独立的改变他们之间的交互

备忘录模式

  • 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

观察者模式

  • 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
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
package main

// Listener 观察者接口
type Listener interface {
DoSomething() // 观察者接到通知时做的事情
}

// Notifier 通知者
type Notifier interface {
AddListener()
DeleteListener()
Notify()
}

// StudentZhangSan 张三同学
type StudentZhangSan struct{}

// DoSomething 张三在接到通知时做的事情
func (StudentZhangSan) DoSomething() {}

// StudentLiSi 李四同学
type StudentLiSi struct{}

// DoSomething 李四在接到通知时做的事情
func (StudentLiSi) DoSomething() {}

// Monitor 班长
type Monitor struct {
ListenerList []Listener
}

// AddListener 添加观察者
func (monitor *Monitor) AddListener(listener Listener) {
monitor.ListenerList = append(monitor.ListenerList, listener)
}

// DeleteListener 删除观察者
func (monitor *Monitor) DeleteListener(listener Listener) {
for index, listenerInList := range monitor.ListenerList {
if listener == listenerInList {
monitor.ListenerList = append(monitor.ListenerList[:index], monitor.ListenerList[index+1:]...)
}
}
}

// Notify 通知观察者
func (monitor *Monitor) Notify() {
for _, listener := range monitor.ListenerList {
listener.DoSomething()
}
}

func main() {
// 创建观察者
var studentZhangSan = new(StudentZhangSan)
var studentLiSi = new(StudentLiSi)

// 创建通知者
var monitor = new(Monitor)
// 添加观察者
monitor.AddListener(studentZhangSan)
monitor.AddListener(studentLiSi)
// 发送通知
monitor.Notify()
}

状态模式

  • 对象的行为,依赖于它所处的状态

策略模式

  • 准备一组算法,并将每一个算法封装起来,使得它们可以互换
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
package main

// WeaponStrategy 武器策略
type WeaponStrategy interface {
UseWeapon() // 使用武器
}

// AK47 具体武器AK47
type AK47 struct{}

func (AK47) UseWeapon() {}

// Knife 具体武器匕首
type Knife struct{}

func (Knife) UseWeapon() {}

// Hero 英雄类
type Hero struct {
WeaponStrategy WeaponStrategy
}

// SetWeaponStrategy 设置当前武器
func (hero *Hero) SetWeaponStrategy(weaponStrategy WeaponStrategy) {
hero.WeaponStrategy = weaponStrategy
}

// UseWeaponStrategy 使用当前武器
func (hero *Hero) UseWeaponStrategy() {
hero.WeaponStrategy.UseWeapon()
}

func main() {
// 创建英雄
var hero = new(Hero)

// 使用AK47
hero.SetWeaponStrategy(new(AK47))
hero.UseWeaponStrategy()

// 使用匕首
hero.SetWeaponStrategy(new(Knife))
hero.UseWeaponStrategy()
}

模板方法模式

  • 子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
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
package main

// Beverage 制作饮料过程
type Beverage interface {
// BoilWater 烧水
BoilWater()
// Brew 冲泡
Brew()
// PourInCup 倒入杯中
PourInCup()
}

// BeverageTemplate 制作饮料过程模板
type BeverageTemplate struct {
beverage Beverage
}

// MakeBeverage 制作饮料
func (beverageTemplate *BeverageTemplate) MakeBeverage() {
if beverageTemplate == nil {
return
}

// 固定流程
beverageTemplate.beverage.BoilWater()
beverageTemplate.beverage.Brew()
beverageTemplate.beverage.PourInCup()
}

// MakeCoffee 制作咖啡
type MakeCoffee struct {
BeverageTemplate
}

func (MakeCoffee) BoilWater() {}
func (MakeCoffee) Brew() {}
func (MakeCoffee) PourInCup() {}

// NewMakeCoffee 构造方法
func NewMakeCoffee() *MakeCoffee {
var makeCoffee = new(MakeCoffee)
makeCoffee.beverage = makeCoffee
return makeCoffee
}

// MakeJuice 制作果汁
type MakeJuice struct {
BeverageTemplate
}

func (MakeJuice) BoilWater() {}
func (MakeJuice) Brew() {}
func (MakeJuice) PourInCup() {}

// NewMakeCoffee 构造方法
func NewMakeJuice() *MakeJuice {
var makeJuice = new(MakeJuice)
makeJuice.beverage = makeJuice
return makeJuice
}

func main() {
// 制作咖啡
var makeCoffee = NewMakeCoffee()
makeCoffee.MakeBeverage()

// 制作果汁
var makeJuice = NewMakeJuice()
makeJuice.MakeBeverage()
}

访问者模式

  • 表示一个作用于某对象结构中的各元素的操作,通过访问者模式可以在不改变各元素的类的前提下定义作用于这些元素的新操作

完成

参考文献

哔哩哔哩——刘丹冰AceId