背景
以商城订单处理为例,针对不同订单,需要采取不同的策略。
- 买菜的订单,需要整合订单信息,分配调度任务给不同的仓库
- 拼单,需要等待拼单完成,下发订单给对应商家
- 正常订单,在下单完成后,无需等待,直接下发给商家
策略模式可以将一系列算法封装起来,对算法进行编排,满足某一个功能的多种策略需求
策略模式优点
- 可以避免多重条件判断
- 公共代码的可复用性更强
- 本身符合开闭原则
- 能更好的适配上下文比较多的场景
策略模式缺点
- 需要使用者了解不同策略之间的区别
- 会产生多个策略类
具体实现
- 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
demo
以上述订单处理为例
策略类
type OrderStrategy interface {
Handle(ctx context.Context) error
}
买菜订单处理类
type VegeOrderStrategy struct {
City string
OrderID string
}
func (s *VegeOrderStrategy) Handle(ctx context.Context) error {
// pre handle
// order allocate
// order distribute
// after handle, msg notify
return nil
}
拼单订单处理类
type SpliceOrderStrategy struct {
Sum int
OrderID string
}
func (s *SpliceOrderStrategy) Handle(ctx context.Context) error {
// pre handle
// wait notify
// distribute
// after handle, msg notify
return nil
}
正常订单处理类
type NormalOrderStrategy struct {
OrderID string
}
func (s *NormalOrderStrategy) Handle(ctx context.Context) error {
// pre handle
// order distribute
// check confirm
// after handle, msg notify
return nil
}
上下文
type OrderContext struct {
OrderStrategy OrderStrategy
}
func (c *OrderContext) Handle(ctx context.Context) error {
return c.OrderStrategy.Handle(ctx)
}
main.go
func main() {
VegeOrderStrategy := &VegeOrderStrategy{
City: "Beijing",
OrderID: "123456",
}
handler := &OrderContext{
OrderStrategy: VegeOrderStrategy,
}
handler.Handle(context.Background())
}