Strategy Pattern

策略模式(Strategy Pattern) 是一个非常常用的设计模式. 只要是 面向对象编程(Object-oriented programming) 就少不了策略模式的身影.

1 设计原则

封装变化.
多用组合(composition), 少用继承(inheritance).
针对接口编程(多态), 不针对实现编程.

2 策略模式

定义一个算法接口;
把不同的算法封装起来;
各个算法之间可以相互替换;
算法的调用者 不用了解 算法的细节 和 算法的变化.

参考 <Head First 设计模式> 中给的一个例子:
有多种不同的鸭子, 不同种的鸭子有不同的行为.
比如 红头鸭, 绿头鸭, 橡皮鸭 等, 它们的外观, 飞行行为, 鸣叫行为都不同.

我们看以下三种设计方式(以下截图来源网络, 由于是从书上截的图, 不是自己画的图, 所以会有一些不相干的信息…请看类图, 忽略其他的信息).
方式1:
strategyPattern_1
每一种鸭子都 继承 一个 Duck 基类, 然后根据需要重写基类里面的方法.

方式1 会有几个问题:
1, 代码在多个子类中重复. 比如, A鸭 和 B鸭 的 飞行行为 是相同的, 但我们却要在 两个类中 写同样的飞行行为 代码.
2, 很难知道所有鸭子的全部行为(除了飞行, 鸣叫, 还有别的行为吗?). 这导致在基类 Duck 中新加一个行为(比如行走)时, 我们不得不修改所有的子类. 真是牵一发而动全身.
3, 运行时的行为不容易改变.

方式2:
strategyPattern_2
不全用 继承, 把基础的行为放在 Duck 基类里, 把可能不是所有种类鸭子都有的行为(飞行等)提取出来, 放到接口中, 只有有特定行为的鸭子才 实现 这种行为.
这样虽然解决了一部分问题:不会牵一发而动全身了.
但是, 这样代码还是 无法复用! 相同的 飞行行为 还是要在多个 实现类里重复写.

方式3:
strategyPattern_3
把会变行为封装起来. 如上图所示, 把飞行行为 和 鸣叫行为 定义为接口, 并有一些具体的实现.

strategyPattern_4
把封装好的飞行行为 和 鸣叫行为 组合Duck 基类 中.
我们把 鸭子的飞行和鸣叫 委托FlyBehaviorQuackBehavior, 而不是在 Duck 中实现.
FlyBehaviorQuackBehavior 就是两个算法族, 里面有很多可以换着使用的算法.
不同的鸭子类(调用者)可以 复用 不同的具体的 FlyBehavior / QuackBehavior.
方式 3 就是 策略模式 的思想.

3 使用案例

仓库备货售卖:
仓库的货的来源有两种(以后可能会加别的方式): 商家买入 和 用户退货.
这两种来源的数据在 wms(warehouse manage system) 的 入库 的方式不同.
我们可以定义一个 入库策略StockInStrategy, 然后有 商家买入用户退货 两个具体实现.
在需要做入库操作时, 只要根据运行时的参数, 选择具体的 入库策略 即可.

热卖榜单:
封装不同的榜单(品牌榜, 新手榜, 普通热卖等等).

快递路由查询:
封装不同的快递服务(顺丰, 京东, EMS 等等).

Reference

[1]. Head First 设计模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值