[Golang修仙之路] 策略模式

1. 什么是「策略模式」?

个人的理解就是, 实现同一件事情, 可能有不同的算法/策略, 通过使用策略模式, 可以让策略的选择更平滑, 添加/删除一个策略更方便(因为符合开闭原则, 扩展性更好).

2. 策略模式的实现

首先要定义一个策略接口, 有若干不同策略的具体实现去实现这个接口. 然后对于策略的使用者, 只需要依赖抽象的策略接口, 然后通过一个SetStrategy()设置策略的方法, 来指明当前抽象接口选择哪个具体实现(这也是多态的体现). 最后调用抽象策略接口定义的具体方法即可.

2.1 具体场景Demo

光这样说肯定不好理解, 下面我来举1个例子, 这个例子的场景是我自己想的, 不是抄的.

篮球场上有多种不同的防守战术, 我们认为每一种战术是一个「策略」.

首先定义防守策略接口:

golang 复制代码
package interfaces

type Defend interface {
	Defend()
}

然后写几个具体实现, 意思一下hhh

golang 复制代码
// strategy 1
type Focus struct{}

func (f *Focus) Defend() {
	fmt.Println("执行盯人包夹防守战术")
}

// strategy 2
type OneOnOne struct{}

func (o *OneOnOne) Defend() {
	fmt.Println("执行一对一防守战术")
}

// strategy 3
type TwoThree struct{}

func (t *TwoThree) Defend() {
	fmt.Println("执行二三联防战术")
}

然后通过一个很多文章上叫Context的类, 去承担 设置策略 + 执行策略 的工作. 我们这里搞了一个 Coach教练类, 来设置防守战术 并 敦促队员执行.

可以看到, Coach类内部确实只依赖接口, Coach对策略的增加/减少是无感的, 扩展性好.

golang 复制代码
type Coach struct {
	name string
	defendStrategy interfaces.Defend
}

func (c *Coach) SetDefendStrategy(strategy interfaces.Defend) {
	fmt.Printf("%s 切换防守策略\n", c.name)
	c.defendStrategy = strategy
}

func (c *Coach) ExecuteDefend() {
	c.defendStrategy.Defend()
}

func NewCoach(name string) *Coach {
	return &Coach{
		name: name,
	}
}

最后我们执行main函数, 并看一下效果:

golang 复制代码
func main() {
    coach := NewCoach("波波维奇")
    coach.SetDefendStrategy(&strategies.Focus{})
    coach.ExecuteDefend()

    coach.SetDefendStrategy(&strategies.OneOnOne{})
    coach.ExecuteDefend()
}

程序运行成功, 但是我们注意到, 在main函数中, 我们确实要创建策略的具体实现的实例来作为参数传入, 这一点也被归为策略模式的缺点之一. 但是我认为, 不这么写还能怎么写呢, 策略模式总比直接依赖具体实现的方式要强得多.

3. 策略模式的优缺点

3.1 优点

  1. 符合开闭原则, 扩展性好, 因此在多人合作的时候, 代码易于维护(增加策略的时候, 只需要关注策略的具体实现)
  2. 可以在运行时切换策略.
  3. 可以将策略的具体实现和策略的使用这两部分代码隔离开来.

3.2 缺点

  1. 每种策略都对外暴露. (如果这也算缺点的话)

4. 参考

  1. 《设计模式》: refactoringguru.cn/design-patt...
  2. 刘丹冰, Easy设计模式: www.bilibili.com/video/BV1Eg...

5. 题外话

一点思考, 我之前学习的时候, 总是有一个地方不懂就钻牛角尖总想弄懂, 可是有些问题弄懂了面试也不问, 过了一段时间也忘记了, 对写更优雅的代码也没有帮助. 那么不如松弛一点, 尽力弄懂当前阶段能弄懂的即可, 一本武林秘籍, 给不同修为的人看, 他们能领悟的东西也是不同的吗.

杜绝"一个知识点只看一次, 一次看透"这个思想, 小猪乔治跟自己说.

相关推荐
路弥行至11 小时前
【Head First 设计模式】第 2 章:观察者模式 —— 用现代 C++ 重新解读“交互对象的松耦合
c++·经验分享·笔记·观察者模式·设计模式·入门教程·headfirst
YYYing.12 小时前
【设计模式系列 (九) 】装饰器模式
c++·后端·设计模式·装饰器模式·c/c++
沫璃染墨15 小时前
《从零入门Linux系统篇(五十六):线程篇·九——生产者消费者模型:从条件变量到BlockingQueue实现》
linux·服务器·c++·驱动开发·设计模式·架构·系统架构
c萱2 天前
AI产品经理——01基础认知篇
设计模式·prompt·aigc·产品经理·ai编程·gitcode·ai-native
YYYing.2 天前
【设计模式系列 (八) 】组合模式
c++·后端·设计模式·组合模式·c/c++
geovindu2 天前
rust: Composite Pattern
开发语言·后端·设计模式·rust·组合模式
YYYing.2 天前
【设计模式系列 (七) 】桥接模式
c++·后端·设计模式·桥接模式
阿狗童鞋3 天前
设计模式实战指南
设计模式
电子科技圈3 天前
基于车载SerDes和OpenGMSL协议的SoC设计与验证:行业高频问题解析
设计模式·车载系统·软件构建·设计规范
ClinicTech3 天前
高速冷冻离心机的温控系统与安全保护逻辑解析
设计模式·架构·健康医疗·设计语言