Go设计模式-策略模式

252 阅读2分钟

什么是策略模式

策略模式可以让开发者定义一系列算法,并且将每种算法分别放入独立的类,从而使得算法的对象可以相互替换

组成;

  • 上下文(Context): 维护指向具体策略引用的类,并且仅通过策略接口与该引用进行交流
  • 策略(Stategy): 实现上下文所用算法的通用接口,它声明了一个上下文,用于执行策略的方法
  • 具体策略(ConcreteStrategy):实现上下文所用算法的各种不同的变体的类。当上下文需要运行算法时,具体的策略会在其已连接的的策略对象上调用执行方法
  • 客户端(Client): 创建一个特定策略的对象并将其传递给上下文,上下文会提供一个设置器,以便客户端在运行时替换相关联的策略

代码实现

package main

import "fmt"

// IStrategy 策略接口
type IStrategy interface {
   Execute()
}

/*
定义具体策略类及其方法
具体策略类必须实现策略接口
*/
// strategyA 具体策略类
type strategyA struct {
}

func (a strategyA) Execute() {
   fmt.Println("策略A")
}

// strategyB 具体策略类
type strategyB struct {
}

func (b strategyB) Execute() {
   fmt.Println("策略B")
}

// NewStrategyA 创建具体策略类strategyA的新对象
func NewStrategyA() IStrategy {
   return &strategyA{}
}

// NewStrategyB 创建具体策略类strategyB的新对象
func NewStrategyB() IStrategy {
   return &strategyB{}
}

/*
定义上下文及其方法
上下文类中添加一个成员变量,用于存储对策略对象的引用
然后提供相应的设置器,用于修改成员变量
*/

// Context 上下文类
type Context struct {
   strategy IStrategy
}

// SetStrategy 设置上下文对象执行的具体策略对象
func (c *Context) SetStrategy(strategy IStrategy) {
   c.strategy = strategy
}

// Execute 上下文类的方法
func (c *Context) Execute() {
   c.strategy.Execute()
}

func NewContext() *Context {
   return &Context{}
}

func main() {
   strategyB := NewStrategyB()
   context := NewContext()
   context.SetStrategy(strategyB)
   context.Execute()
}

适用场景

  • 需要使用对象中各种的不同的算法变体,并且希望能在运行时切换算法时,可以使用策略模式
  • 有许多仅在执行某些行为时略有不同的相似类时,可以使用策略模式

优缺点

优点

  • 部分算法可重用
  • 子类化的代替方法
  • 策略模式消除了条件语句
  • 可以提供相同行为的不同实现
  • 符合开闭原则

缺点

  • 如果算法极少发生改变,则会让程序过于复杂
  • 策略模式会让对象数量增加