持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
前言
策略模式是程序员必知必会的一种设计模式,也是设计模式种最简单的一种。说到策略模式,都知道其是为了消除 if else 语句的。因为多重条件语句不易维护,策略模式就可以解决 if else 或 switch case 语句的。
先分析下传统的 if ...else 语句
if cond == "AAA" {
println("我是 AAA 策略")
DoAAA()
} else if cond =="BBB" {
println("我是 BBB 策略")
DoBBB()
} else if cond == "CCC" {
println("我是 CCC 策略")
DoCCC()
}
代码设计
根据条件 cond 判断执行哪个策略,那我们可以进行一层抽象,对外的告诉我何种策略,然后就能执行对应的策略。
// 对象对应的策略方法
AAA: DoAAA()
BBB: DoBBB()
CCC: DoCCC()
// 抽象一个执行策略接口
type IStrategyObj interface {
DoStrategy()
}
type StrObeject1 struct {
Name string
}
func (str *StrObeject1) DoStrategy() {
// AAA 策略执行
println(str.Name + " 策略执行")
}
type StrObeject2 struct {
Name string
}
func (str *StrObeject2) DoStrategy() {
// BBB 策略执行
println(str.Name + " 策略执行")
}
定义不同的策略后,还需要一个主体,主体需要做的只是执行不同的策略,且必须是能够接受各种不同策略对象,然后告知策略对象,执行策略。
type MainPart struct {
sub IStrategyObj
}
func (mp *MainPart) SetStratey(sub IStrategyObj) {
mp.sub = sub
}
func (mp *MainPart) DoStrategy() {
mp.sub.DoStrategy()
}
这部分就是用来转换if else ,这样就无需加很多判断条件,仅需告知哪个策略对象即可,然后执行策略时就会执行到对应的策略方法。
定义完后执行下结果:
// 执行策略模式
AAstrategy := pattern.StrObeject1{"我是AA"}
BBstrategy := pattern.StrObeject2{"我是BB"}
mp := pattern.MainPart{}
mp.SetStratey(&AAstrategy)
mp.DoStrategy()
mp.SetStratey(&BBstrategy)
mp.DoStrategy()
println("执行结束")
组成
从代码上分析可以看到,有三部分组成:
- 抽象策略:公共的接口,定义一个 interface ,其中包含方法
- 具体策略:实现了抽象策略定义的接口,具体方法的实现
- 执行策略的主体:支持接收不同的策略对象,然后给客户端调用。
优缺点
- 遵循开闭原则,不修改源码,灵活增加新的策略,扩展性良好
- 避免多重条件的判断
应用场景
- 对于同类问题不同解决方法,且每个解决方法都是独立的。如支付时,有各种不同的支付方式。
- 需要自由切换选择不同类型的算法场景