行为型:策略模式
睡不醒的鲤鱼 2022-10-16 Golang Go 进阶
# 一、策略的定义
策略模式(Strategy Pattern)定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。
# 二、使用场景
在项目开发中,我们经常要根据不同的场景,采取不同的措施,也就是不同的 策略。比如,假设我们需要对 x、y 这两个整数进行计算,根据条件的不同,需要执行不同的计算方式。我们可以把所有的操作都封装在同一个函数中,然后通过 if ... else ... 的形式来调用不同的计算方式,这种方式称之为 硬编码。
在实际应用中,随着功能和体验的不断增长,我们需要经常添加 / 修改策略,这样就需要不断修改已有代码,不仅会让这个函数越来越难维护,还可能因为修改带来一些 bug。所以为了解耦,需要使用策略模式,定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法(即策略)。
# 三、策略的实现
package strategy
// IStrategy 策略接口定义
type IStrategy interface {
do(int, int) int
}
// 策略实现:加
type add struct{}
func (a *add) do(x, y int) int {
return x + y
}
// 策略实现:减
type reduce struct{}
func (r *reduce) do(x, y int) int {
return x - y
}
// Operator 具体策略的执行者
type Operator struct {
strategy IStrategy
}
// 设置策略
func (o *Operator) setStrategy(strategy IStrategy) {
o.strategy = strategy
}
// 调用策略中的方法
func (o *Operator) calculate(x, y int) int {
return o.strategy.do(x, y)
}
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
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
在上述代码中,我们定义了策略接口 IStrategy
,还定义了 add
和 reduce
两种策略。最后定义了一个策略执行者,可以设置不同的策略,并执行,例如:
func TestStrategy(t *testing.T) {
operator := Operator{}
operator.setStrategy(&add{})
result := operator.calculate(1, 2)
fmt.Println("add:", result)
operator.setStrategy(&reduce{})
result = operator.calculate(2, 1)
fmt.Println("reduce:", result)
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
可以看到,我们可以随意更换策略,而不影响 Operator
的所有实现。