参考文章
- 美团技术-设计模式二三事
- 美团技术-设计模式在外卖营销业务中的实践
- 设计模式之美-策略模式
策略模式(Strategy或Policy)是一个很通用的设计模式,在DDD架构中会经常出现,其核心就是封装领域规则。
策略模式主要由这三个角色组成,环境角色(Context)、抽象策略角色(Strategy)和具体策略角色(ConcreteStrategy)。
- 环境角色(Context):持有一个策略类的引用,提供给客户端使用。
- 抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略角色(ConcreteStrategy):包装了相关的算法或行为。
一个Strategy是一个无状态的单例对象,通常需要至少2个方法:
- canApply
- 业务执行方法
其中,canApply方法用来判断一个Strategy是否适用于当前的上下文,如果适用则调用方会去触发业务方法。通常,为了降低一个Strategy的可测试性和复杂度,Strategy不应该直接操作对象,而是通过返回计算后的值,在Domain Service里对对象进行操作。
策略模式的应用情形
- 最基础的策略模式情形
- 策略处理过程
- 输入参数是一样的,输出结果是一样的,也就是说多种策略可以完美的继承基类策略。
- 只选择单一策略进行处理
- 策略的选择过程不算复杂
- 解决方式:
- 定义一个策略基类,所有策略都继承基类,各自实现。(作用:将策略定义代码分离出业务逻辑)
- 处理过程优化为使用策略基类统一处理
- 可选:选择过程可以优化为查表法
- 可选:策略可以提取创建好,存到表中(配合查表法或者工厂方法)
- 策略处理过程
- 复杂策略模式
- 策略处理过程
- 输入参数是不一样的,但输出结果是一样的,不好直接继承基类策略。
- 只选择单一策略进行处理
- 策略的选择过程不算复杂
- 解决方式:
- 定义一个策略基类,所有策略都继承基类,各自实现。(作用:将策略定义代码分离出业务逻辑)
- 若输入参数不复杂,可以采用Map的形式进行传递
- 若输入参数复杂,则定义一个策略上下文基类,然后为每个策略定义策略上下文子类。
- 从业务逻辑生成对应策略上下文的胶水代码可以汇总到一个类中,作为DP。
- 处理过程优化为使用策略基类+策略上下文基类(或者Map)统一处理
- 可选:选择过程可以优化为查表法
- 可选:策略可以提取创建好,存到表中(配合查表法或者工厂方法)
- 策略处理过程
- 更复杂的策略模式
- 策略处理过程
- 输入参数是不一样的,但输出结果也不一定一样,不好直接继承基类策略。
- 可以选择多种策略进行处理
- 策略的选择过程复杂
- 解决方式:此时应该采用职责链模式去解决。
- canApply
- 一个业务方法
- 这个涵盖了上述情况,都可以解决。
- 策略处理过程