一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
策略模式是对象行为模式,主要通过对算法进行封装,把使用者和算法实现分割开,然后根据不同的条件使用不同的算法。比如乘坐交通工具时,可能是飞机,火车或者自驾。再比如,不同商品有不同的打折,不同的活动有不同的商品活动价位等等场景。
策略模式的核心是组织这些算法,从而让程序结构更加灵活,使得程序更好维护和扩展。基于策略模式,需要参与的角色:
- 抽象策略 ConStrategy :公共接口,不同策略算法实现该接口。
- 具体策略 Strategy :实现抽象策略定义的接口,是对算法的具体实现
- 环境类 Context :对策略类的应用,最终是给客户端调用的
type IStrategy interface {
doHandler(int, int) int
}
type add struct{}
func (*add) doHandler(a, b int) int {
return a + b
}
type multiply struct{}
func (*multiply) doHandler(a, b int) int {
return a * b
}
type OperateStrategy struct {
strategy IStrategy
}
func (operator *OperateStrategy) SetStrategy(strategy IStrategy) {
operator.strategy = strategy
}
func (operator *OperateStrategy) calculate(a, b int) int {
return operator.strategy.doHandler(a, b)
}
可以看到,抽象策略有一个 doHandler 的方法,具体的策略实现接口,实现了方法,一个加法 一个乘法。环境类就是 OperateStrategy ,有一个设置策略的方法,和使用策略的方法。所以这样使用:
oper := OperateStrategy{}
oper.SetStrategy(&add{})
result := oper.calculate(1, 2)
fmt.Println("和结果是", result)
OperateStrategy 是具体策略的执行者,先设置它应该使用的策略,然后再调用该策略的执行方法。这样外部使用的时候只需要通过策略执行人去执行详细的算法,这样把算法责任和算法本身分开,让不同对象承载不同的算法。
所以,我们通过以上观察:
- 策略模式符合开闭原则,可以灵活扩展算法,而不需要去修改原算法
- 策略模式可以避免使用多重条件语句
- 分类了算法的使用和算法的具体实现
但,如果算法多的话就需要都要了解所有的算法,这样才能知道什么场景用哪个,且如果太多的算法也会增加维护难度。