Go 设计模式-策略模式

143 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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 ,其中包含方法
  • 具体策略:实现了抽象策略定义的接口,具体方法的实现
  • 执行策略的主体:支持接收不同的策略对象,然后给客户端调用。

优缺点

  • 遵循开闭原则,不修改源码,灵活增加新的策略,扩展性良好
  • 避免多重条件的判断

应用场景

  • 对于同类问题不同解决方法,且每个解决方法都是独立的。如支付时,有各种不同的支付方式。
  • 需要自由切换选择不同类型的算法场景