两年前写过一篇PHP策略模式的文章,最近在做公司Go项目时也用到了策略模式,那就写一篇文章记录下来吧。
首先还是编写一个基类接口用于定义策略规范及实现逻辑方法
// MyBaseStrategy 策略公共接口
type MyBaseStrategy interface {
MakeImplementation() (string, error)
}
接着声明好策略执行者,再编写一个策略生成的工厂类用于返回策略执行者的实现逻辑
// MyBaseOperator 策略执行者
type MyBaseOperator struct {
// 嵌入策略接口,就不需要再声明实现方法了
MyBaseStrategy
}
// NewMyOperator 策略执行者工厂方法
func NewMyOperator(strategy MyBaseStrategy) *MyBaseOperator {
// 返回策略执行者,并将具体策略嵌入
return &MyBaseOperator{strategy}
}
// GetOperatorByPlanName 通过计划名称获取策略执行者
func GetOperatorByPlanName(planName string) *MyBaseOperator {
operator := NewMyOperator(map[string]MyBaseStrategy{
"A": NewMyPlanAImplementationStrategy(),
}[planName])
return operator
}
最后编写具体策略实现
// MyPlanAImplementationStrategy A计划实现策略类
type MyPlanAImplementationStrategy struct {
}
// MakeImplementation A计划策略执行具体方法
func (plan *MyPlanAImplementationStrategy) MakeImplementation () (string, error) {
return "This is my a plan class of implementation function", nil
}
// NewMyPlanAImplementationStrategy A计划实现策略类工厂方法
func NewMyPlanAImplementationStrategy() *MyPlanAImplementationStrategy {
return &MyPlanAImplementationStrategy{}
}
调用策略的时候,就可以配合工厂类去动态生成策略实现类来执行逻辑
// 根据名称创建A计划执行者
thePlan := GetOperatorByPlanName("A")
// 执行A计划
result, err := thePlan.MakeImplementation()
// 有错误返回则抛出错误
if err != nil {
panic(err)
}
fmt.Println(result)
这样就可以动态扩展多个策略,动态去调用某个具体策略去执行,起到最终程序解耦的效果,应用场景包括支付对接、计划执行等等。