[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. 题外话

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

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

相关推荐
wwdoffice011012 小时前
304和316不锈钢有什么区别?哪个更好?
设计模式
网小鱼的学习笔记13 小时前
创建型设计模式(工厂、builder、原型、单例)
java·后端·设计模式
逆境不可逃13 小时前
【从零入门23种设计模式21】行为型之空对象模式
java·开发语言·数据库·算法·设计模式·职场和发展
蜜獾云1 天前
设计模式之命令模式:给其他模块下达命令
设计模式·命令模式
小湘西1 天前
拓扑排序(Topological Sort)
python·设计模式
蜜獾云2 天前
设计模式之观察者模式:监听目标对象的状态改变
观察者模式·设计模式·rxjava
知无不研2 天前
中介者模式
c++·设计模式·中介者模式
bmseven2 天前
大白话讲解23种设计模式简介
设计模式
蜜獾云2 天前
设计模式之代理模式:本地接口代理远程接口的调用
设计模式·系统安全·代理模式
蜜獾云2 天前
设计模式之访问者模式:动态的给目标对象增加新功能
设计模式·访问者模式