纯技术

Go 设计模式:策略模式

策略模式可以让开发者定义一系列算法,并且将每种算法分别放入独立的类,从而使得算法的对象可以相互替换 组成; 上下文(Context): 维护指向具体策略引用的类,并且仅通过策略接口与该引用进行交流 策略(Stategy): 实现上下文所用算…

3 分钟阅读
精选技术记录
持续迭代更新
Share

什么是策略模式

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

组成;

  • 上下文(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()
}

适用场景

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

优缺点

优点

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

缺点

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

本文同步自掘金

如果发现内容有误或需要更新,请访问掘金原文进行查看。

Share

如果这类内容对你有帮助

这里放了一个阿里云 AIGC 活动入口。如果你本来就有相关需求,可以顺手了解;如果产生推广收益,我会优先用于支付服务器、域名和网站维护费用。

看看阿里云 AIGC 活动

相关文章

纯技术2025年8月21日

为什么有的人学了很多年的编程,还是只会【增删改查】?

为什么你写了多年代码,技术栈还停留在"增删改查"? 我们不妨从一个常见的开发者画像开始:工作数年,日常任务是理解需求、实现业务逻辑、提供数据接口。在熟悉的框架下,每天熟练地进行着数据库的增、删、改、查(CURD)操作,周而复始。 这套流程看…

纯技术2023年12月21日

Golang-常用限流算法实现

常用的限流算法有一下4中实现方式: 令牌桶 漏桶 计数器 滑动窗口 令牌桶以恒定的速度向桶里加入令牌,桶满了则不再加入令牌。当服务收到请求时尝试从桶中取出一个令牌,如果可以获取到令牌,则继续执行后续的业务,否则返回超限错误码或对应的错误页面…

纯技术2023年12月21日

go-zero 使用 Consul 作为注册中心

go-zero 默认使用etcd作为注册中心,如果我们的业务使用的consul, 可以使用zero-contrib中的consul包进行替代 文件位置:ect/**.yaml 增加consul配置 服务启动后即可在conusl/ui上查看到…