Strategy Design Pattern
什么是策略?
将系列算法(策略)定义在单独的类中,以组合的方式被使用。实现算法实现与使用方的松耦合。
典型的场景是与模板模式结合:例如把支付流程做成模板(下单 => 计算优惠 => 创建订单 => 支付 ...),在付钱这一步,根据不同的支付渠道有不同的策略:
- 美团支付
- 微信支付
- 支付宝支付
- ...
当然也不局限于此~
策略模式如何封装变化?
策略模式可以结合模板模式,实现变化点的延伸,把回调函数变成接口,还能动态排布成数组。
跟着模板模式的中的需求,如果变得更复杂,回家要同时乘坐多种交通工具,先坐火车,再坐飞机。如果在模板模式下怎么实现?
写一个新的子类 goHomeByTrainAndAirplane 来实现,这样又会导致新的代码重复(goHomeTrain 和 goHomeAirplane 的逻辑在这个新子类中重复。而且也不灵活了,如果有个先坐飞机再做火车,又增加一个子类?
这里的变化是回家方式,我们要想办法将变化封装,实现 OCP。怎么做呢?
思路其实与模板模式中的回调类似,把变化的东西抽象出来,这里变化的是回家方式,可以定义一个 Travellable 策略接口,不同的交通方式实现该接口:
public interface Travellable {
void travel();
}
public class ByAir implements Travellable {}
public class ByTrain implements Travellable {}
// ...
这就是所谓的策略模式了。
变化抽离了,我们也要对模板进行一些修改,在使用的时候把对应的变化注入进去:

- 把整个回家过程定义为一个 Travel 列表
- 新增添加/查询 Travel 的方法
travel()
方法变成执行每一个 Travel 策略
这样就成功剥离了变化,在不同的场景下注册不同的策略执行模板。
对于更复杂的问题,我们选择了策略模式,这并不意味着策略模式比模板方法模式好,只是在此场景使用策略模式会更好地解决问题,用什么模式要看场景。
总结
通过这种设计,我们实现了:
- 高内聚:每个策略负责一件事情
- 松耦合:
- 如果新增一种交通方式,只需要增加一个新的策略,它们之间独立实现,互不干扰
- 调用者只依赖策略接口
- 复用:封装好的方法以后可以一直使用