策略模式

问题
为Duck超类扩展fly()方法,影响所有子类。可能使某些不适合子类(橡胶玩具鸭)具备该行为。
继承
- 使扩展牵一发动全身,父类改变造成子类不想要改变。
- 运行时的行为不容易改变
继承+重写
- 代码冗余复杂,处理同一行为的不同表现时麻烦
- 子类可以覆盖父类的方法,所以不知道子类的具体行为
继承接口(Flyable)
- 可以避免继承时的出现有不应具有的的行为而大量覆盖,在Java 8中可以用默认方法实现和继承效果一样的代码复用
- 难以实现代码复用。某一行为在子类中都具有,却有不同实现时,仍然有代码重复的问题
- 在获取到父类时,必须得先用instance of判断是否实现某接口,才能转换类型使用相关方法
[
解决
- 设计原则 - 开放封闭(对扩展开放,对修改封闭)
- 把会变化的部分封装起来,减少其他部分影响。使变化引起不经意后果最小,增加系统弹性
- 设计原则 - 针对接口编程,而非针对实现编程
- 上述方法行为来自Duck超类的具体实现,或子类继承某个接口自行实现
- 即“针对超类型 (supertype) 编程”, 可以在运行时动态改变实现
- 多用组合,少用继承
- 使用组合代码结构具有更大弹性,可以将算法族封装成类,并在运行时动态改变行为。动态改变实现
设计模式 - 策略模式

- 定义了算法族,分别封装起来,使算法可以相互替换。此模式让算法变化独立于使用算法的客户。
良好的OO设计具备的特性
- 可复用
- 可扩充
- 可维护
应用
- 优点
- 支持开闭原则
- 可以在不修改原有系统的基础上选择不同的行为,也可以额外扩展其它行为
- 避免代码冗余
- 避免使用多重条件判定语句
- 安全保密
- 终端使用策略不需要知道如何实现
- 支持开闭原则
- 缺点
- 策略类选择
- 客户端必须知道所有策略类,并自行决定使用哪个策略
- 增加复杂性
- 如果系统复杂会产生很多策略类
- 策略类选择
- 场景
- 行为切换
- 算法选择
- JDK中的Arrays类的sort()方法可以动态地传入比较器
- 通过传入不同的比较器实现算法的替换,而该变化独立于算法的使用者
- org.springframework.beans.factory.support.InstantiationStrategy接口
- 负责使用多种方法创建对应于根bean定义实例
- JDK中的Arrays类的sort()方法可以动态地传入比较器