1. 概述
1.1 作用
策略(Strategy)是用于封装一组算法中单个算法的对象,这些策略可以相互替换,使得单个算法的变化不影响使用它的客户端。
1.1 角色
- Context(环境角色):算法策略的上下文类,也是使用策略对象的客户类
- Strategy(抽象策略):具体策略的抽象接口
- ConcreteStrategy(具体策略):对应了环境各种算法,它是抽象策略的实现。
1.2 类图
2. 代码示例
2.1 设计
- 定义一个抽象策略
- 定义两个具体策略
- 它们实现了抽象策略
- 它们拥有自己的算法
- 定义一个环境类
- 它有x、y两个成员
- 它是策略的聚合,它有方法可以将具体策略加入聚合
- 它的执行方法可以执行之前加入环境的策略组
- 它有方法可以查询它自己
- 调用
- 实例化两个具体策略
- 实例化一个环境,将两个策略加入环境(一个策略可以多次加入)
- 调用环境的执行方法
- 调用环境的查看方法验证结果
2.2 代码
- 代码
package main
import "fmt"
// 定义抽象策略
type Strategy interface {
Calculate(a, b int64) (x, y int64)
}
// 定义具体策略
type AddStrategy struct{}
// 该策略的计算方法(这里我们仅返回了环境的x、y值,你也可以如标准类图所示设计成返回环境类)
func (s *AddStrategy) Calculate(a, b int64) (x, y int64) {
x = a + 10
y = b + 10
return x, y
}
// 定义第二个具体策略
type SubStrategy struct{}
//该策略的计算方法
func (s *SubStrategy) Calculate(a, b int64) (x, y int64) {
x = a - 1
y = b - 1
return x, y
}
// 定义环境类
type Context struct {
strategyList []Strategy
x int64
y int64
}
//创建环境类的函数(该函数为演示方便,和策略模式无关)
func CreateContext(x int64, y int64) *Context {
c := &Context{
x: x,
y: y,
strategyList: []Strategy{},
}
return c
}
//定义方法,为环境添加策略
func (c *Context) AddStrategy(s ...Strategy) {
c.strategyList = append(c.strategyList, s...)
}
//定义方法,执行环境拥有的各策略
func (c *Context) Execute() {
for _, s := range c.strategyList {
c.x, c.y = s.Calculate(c.x, c.y)
}
}
//定义环境的查询方法
func (c *Context) Get() {
fmt.Printf("====context===\n x: %d y:%d\n", c.x, c.y)
}
func main() {
//实例化两个策略
addStrategy := &AddStrategy{}
subStrategy := &SubStrategy{}
//实例化环境
context := CreateContext(200, 100)
//将策略加入环境
context.AddStrategy(addStrategy, subStrategy, subStrategy)
//执行环境中各策略
context.Execute()
//查询环境状态验证结果
context.Get()
}
- 输出
====context===
x: 208 y:108