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

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

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

相关推荐
workflower1 小时前
使用谱聚类将相似度矩阵分为2类
人工智能·深度学习·算法·机器学习·设计模式·软件工程·软件需求
枣伊吕波3 小时前
第六节第二部分:抽象类的应用-模板方法设计模式
android·java·设计模式
lalajh4 小时前
论软件设计模式及其应用
设计模式
lgily-12256 小时前
常用的设计模式详解
java·后端·python·设计模式
周努力.1 天前
设计模式之中介者模式
设计模式·中介者模式
yangyang_z2 天前
【C++设计模式之Template Method Pattern】
设计模式
源远流长jerry2 天前
常用设计模式
设计模式
z26373056112 天前
六大设计模式--OCP(开闭原则):构建可扩展软件的基石
设计模式·开闭原则
01空间2 天前
设计模式简述(十八)享元模式
设计模式·享元模式
秋名RG2 天前
深入理解设计模式之原型模式(Prototype Pattern)
设计模式·原型模式