这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
go语言设计模式 - 策略模式
1. 类图
Context(环境类): 环境类是使用算法的角色,他在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
Strategy(抽象策略类): 它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时间调用具体策略类中实现的算法。
ConcreteStrategy(具体策略类): 它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。
2. 代码如下
package main
import "fmt"
type WeaponStrategy interface {
UseWeapon() // 使用武器
}
// 具体的策略
type Ak47 struct{}
func (ak *Ak47) UseWeapon() {
fmt.Println("使用 AK47 去战斗")
}
type Knife struct{}
func (k *Knife) UseWeapon() {
fmt.Println("使用 匕首 去战斗")
}
// 环境类
type Hero struct {
strategy WeaponStrategy // 拥有一个抽象的策略
}
// 设置一个策略的方法
func (h *Hero) SetWeaponStrategy(s WeaponStrategy) {
h.strategy = s
}
// 业务逻辑 战斗方法
func (h *Hero) Fight() {
h.strategy.UseWeapon() // 调用具体的策略
}
func main() {
hero := Hero{}
// 更换策略1
hero.SetWeaponStrategy(new(Ak47))
hero.Fight()
hero.SetWeaponStrategy(new(Knife))
hero.Fight()
}
3. 优缺点
优点:
- 策略模式提供了对“开闭原则”的完美技术支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
- 使用策略模式可以避免多重条件选择语句,多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑与算法或行为本身的实现逻辑混合在一起,将他们全部硬编码(Hard Coding)在一个庞大的多重选择语句中,比直接继承环境类的办法还有原始和落后。
- 策略模式提供了一种算法的复用机制。由于将算法单独提取出来封装在策略类中,一个词不同的环境类可以方便的复用这些策略。
缺点:
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法,换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
- 策略模式提供了一种算法的复用机制。由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略。
4. 适用场景
准备一组算法,并将每一个算法封装起来,使得他们可以互换。