蕴含角色
- context 策略使用者
- strategy 策略(行为)接口
- strategyImpl 策略的具体实现,通常这些实现也叫算法族
场景案例
demo1-佣金核算
假如当初有三种业绩类型(A,B,C)须要核算佣金,通过业务剖析,三种核算过程都蕴含以下步骤:
- 查问元数据
- 清空重置上一次佣金计算
- 核算佣金
- 判断佣金归属
个别的做法是定义一个核算接口,接口中定义上述办法,而后实现核算接口,在不同的接口实现类中实现相应的细节
// 核算接口public interface ICalculate{ query(); clear(); calculate(); belong();}// A类型业绩核算public class ACalculate implements ICalculate{ // A类型具体实现 query(); clear(); calculate(); belong();}// B类型业绩核算public class BCalculate implements ICalculate{ // B类型具体实现 query(); clear(); calculate(); belong();} // 其余类型...
上述写法中,存在一些问题:
- 如果C类型中没有 clear清空逻辑呢?
- 能够在C类中不去实现clear()办法
- 如果前期业务变更,不须要belong()办法了呢.新增的类型能够不做具体实现,已有的类型呢?须要一一删除belong()办法
- 如果前期新增了逻辑呢?如:核算团队业绩,计算指标完成率
- 须要大量改变已实现的代码
- 因为政策变动,A,B,C采纳全新对立的 query查问,clear清空逻辑,核算和归属逻辑不同
- 最后各种类型的业绩核算,查问清空等逻辑不同,所以实现细节全副放在了核算类中,现在许多办法能够共用,就从新定义接口,并实现query/clear新的逻辑,而后在业绩核算类中注入
这些是工作中实在遇到的状况,问题不言而喻:
- 耦合度高: 算法的实现与算法使用者耦合
- 代码复用低: 如果不同核算类型中用到雷同逻辑,只能复制粘贴
- 拓展性太差: 在核算过程中新增和删除某个环节,会批改大量代码
- 代码不足设计,档次凌乱.
思考:
- 是否将核算过程中用到的核算环节与核算类分来到?
- 如果办法能够共用,在核算类中能够间接注入接口实现
- 即便不能共用,批改或新增核算环节时不须要改变核算类,代码档次更清晰了
- 是否将这些办法形象成接口?
- 依据核算类型的业务需要,这些办法能够有不同的实现
- 核算的环节将不再固定,能够是任意步骤.新增核算环节只须要定义新的行为接口
// 应用策略模式优化// 1. 将核算环节形象为行为接口,即核算过程有哪些行为// 2. 行为接口能够有不同的具体实现,这些实现类能够看成是一个算法族// 3. 通过组合的形式,使核算过程变动多样// 查问策略public interface Query{ query();}// 查问策略算法族public class TypeAQuery{ query(){ //typeA logic }}public class TypeBQuery{ query(){ //typeB logic }}// 清空策略public interface Clear{ clear();} '其余策略(行为) ...'// 业绩类型A的核算public class ACalculate { // 自定义核算环节,自定义核算环节具体实现 private Query query;}// 业绩类型B的核算public class BCalculate { // 自定义核算环节 private Query query; private Clear clear;}// 调用过程中,通过set()办法能够动静替换策略的实现