简介
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式允许客户端选择算法的实现方式,使得客户端和算法之间解耦。
在策略模式中,定义一组算法接口,并将每个算法封装成具体的策略类。客户端可以在运行时选择所需的策略,将其设置到上下文对象中,从而改变对象的行为。
经过这么多的设计模式,我终于拥有一辆马自达,过年了,我要开着我的马自达回家,但是堵车,所以回家的路线就有很多种选择,我可以走高速,我也可以走国道,这都是策略。
Demo
type Strategy interface {
Execute()
}
// NationalRoad 具体策略,国道
type NationalRoad struct {
}
func (n *NationalRoad) Execute() {
fmt.Println("走国道,免费,可能堵车")
}
// Expy 具体策略,高速
type Expy struct {
}
func (e *Expy) Execute() {
fmt.Println("走高速,收费,快,可能也堵车")
}
// Context 上下文对象,维护一个对策略对象的引用
type Context struct {
strategy Strategy
}
func (c *Context) SetStrategy(strategy Strategy) {
c.strategy = strategy
}
func (c *Context) ExecuteStrategy() {
c.strategy.Execute()
}
test
func TestStrategy(t *testing.T) {
// 创建上下文对象
context := &Context{}
// 使用走国道策略
nRoad := &NationalRoad{}
context.SetStrategy(nRoad)
context.ExecuteStrategy()
// 使用走高速策略
expy := &Expy{}
context.SetStrategy(expy)
context.ExecuteStrategy()
}
在这个示例中,Strategy 是策略接口,定义了策略对象要实现的方法。NationalRoad 和 Expy 是具体策略类,分别实现了策略接口的方法。Context 是上下文对象,维护一个对策略对象的引用,可以在运行时选择所需的策略。
在客户端,我们创建了一个上下文对象 context,并分别使用策略A和策略B。通过调用 ExecuteStrategy 方法,上下文对象执行当前设置的策略,输出相应的执行信息。
在不同的策略下,Context 对象的行为发生了改变。
作用和场景
将算法的实现和使用解耦
策略模式将算法的实现封装在具体策略类中,使得客户端可以独立于算法的具体实现,达到解耦的效果。
支持开闭原则
可以轻松添加新的策略类,无需修改已有的代码,符合开闭原则。
简化客户端代码
客户端不需要了解具体的算法实现,只需要选择所需的策略即可。
当一个问题可以有多个解决方案,且可以在运行时选择其中一个解决方案时,适合使用策略模式。
当有很多条件语句用于选择不同的算法时,可以考虑使用策略模式,将每个算法封装到具体的策略类中,避免条件语句的臃肿。
总体而言,策略模式使得算法的实现和使用分离,提高了代码的灵活性和可维护性。它是一种有效的应对多算法场景的设计模式。