- 业务需求
编写鸭子项目,具体需求如下:- 有各种鸭子,如:野鸭、北京鸭子、水鸭等。鸭子有各种行为,如:叫、飞行等
- 显示鸭子的信息。
- 解决方案
- 传统方案
- 方式:编写一个父类,各种具体的类继承父类
- 问题分析:
- 其他鸭子都继承了Duck类,所以fly让所有子类都会飞了,这是不正确的
- 上述问题是继承带来的问题:对类的局部改动,尤其是超类的局部改动,会影响其他部分。会有溢出效应
- 解决方案:
- 为了改进上述问题,我们可以通过覆盖fly方法来解决—》覆盖解决
- 使用覆盖解决有会出现如下问题:
如果有一个玩具鸭子ToyDuck,这样就需要ToyDuck去覆盖Duck的所有实现的方法。—》策略模式
- 策略模式(strategy pattern)
- 基本介绍
- 策略模式中,定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
- 算法体现了几个设计原则
- 把变化的代码从不变的代码中分离出来;
- 针对接口编程而不是具体类(定义策略接口);
- 多重组合/聚合,少用继承(客户通过组合方式使用策略)
- 原理类图
从上图可以看到,客户Context有成员变量strategy或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定 - 使用策略模式解决鸭子问题
思路分析:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。
原则:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为的变化独立于算法的使用者。 - 业务类图
- 代码实现
- 编写FlyBehavior策略接口
package ltd.huazhongyang.strategy.strategy.interfaces; public interface FlyBehavior { void fly(); }
- 编写飞行技术高超类,并实现FlyBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; public class GoodFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞行技术呱呱叫。。。"); } }
- 编写飞行技术一般类,并实现FlyBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; public class BadFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞行技术就那样。。。"); } }
- 编写不会飞行技术类,并实现FlyBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; public class NoFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("没有遨游太空的权力。。。"); } }
- 编写QuackBehavior策略接口
package ltd.huazhongyang.strategy.strategy.interfaces; public interface QuackBehavior { void quack(); }
- 编写嘎嘎叫类,并实现QuackBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; public class GaGaQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("嘎嘎叫。。。"); } }
- 编写咯咯叫类,并实现QuackBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; public class GeGeQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("咯咯叫。。。"); } }
- 编写不会叫类,并实现QuackBehavior接口
package ltd.huazhongyang.strategy.strategy.interfaces.impl; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; public class NoQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("不会叫。。。"); } }
- 编写Duck抽象类,并聚合FlyBehavior和QuackBehavior接口类
package ltd.huazhongyang.strategy.strategy.abstracts; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; public abstract class Duck { private FlyBehavior flyBehavior ; private QuackBehavior quackBehavior ; public Duck(){ } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void fly(){ if(flyBehavior != null){ flyBehavior.fly(); } } public void quack(){ if(quackBehavior != null){ quackBehavior.quack(); } } public abstract void display();//显示鸭子信息 }
- 编写野鸭子类,并继承Duck超类以及实现相关方法
package ltd.huazhongyang.strategy.strategy.abstracts.entends; import ltd.huazhongyang.strategy.strategy.abstracts.Duck; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.GaGaQuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.GoodFlyBehavior; public class WildDuck extends Duck { public WildDuck(){ super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(new GaGaQuackBehavior()); } public WildDuck(FlyBehavior flyBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(new GaGaQuackBehavior()); } public WildDuck(QuackBehavior quackBehavior) { super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(quackBehavior); } public WildDuck(FlyBehavior flyBehavior,QuackBehavior quackBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(quackBehavior); } @Override public void display() { System.out.println("这是野鸭子~~~~~"); } }
- 编写北京鸭子类,并继承Duck超类以及实现相关方法
package ltd.huazhongyang.strategy.strategy.abstracts.entends; import ltd.huazhongyang.strategy.strategy.abstracts.Duck; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.GeGeQuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.GoodFlyBehavior; public class PakingDuck extends Duck { public PakingDuck(){ super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(new GeGeQuackBehavior()); } public PakingDuck(FlyBehavior flyBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(new GeGeQuackBehavior()); } public PakingDuck(QuackBehavior quackBehavior) { super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(quackBehavior); } public PakingDuck(FlyBehavior flyBehavior,QuackBehavior quackBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(quackBehavior); } @Override public void display() { System.out.println("这是北京鸭子"); } }
- 编写玩具鸭子类,并继承Duck超类以及实现相关方法
package ltd.huazhongyang.strategy.strategy.abstracts.entends; import ltd.huazhongyang.strategy.strategy.abstracts.Duck; import ltd.huazhongyang.strategy.strategy.interfaces.FlyBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.QuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.NoQuackBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.GoodFlyBehavior; public class ToyDuck extends Duck { public ToyDuck(){ super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(new NoQuackBehavior()); } public ToyDuck(FlyBehavior flyBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(new NoQuackBehavior()); } public ToyDuck(QuackBehavior quackBehavior) { super.setFlyBehavior(new GoodFlyBehavior()); super.setQuackBehavior(quackBehavior); } public ToyDuck(FlyBehavior flyBehavior,QuackBehavior quackBehavior) { super.setFlyBehavior(flyBehavior); super.setQuackBehavior(quackBehavior); } @Override public void display() { System.out.println("这是玩具鸭子~~~~~"); } }
- 创建启动类
package ltd.huazhongyang.strategy.strategy; import ltd.huazhongyang.strategy.strategy.abstracts.entends.PakingDuck; import ltd.huazhongyang.strategy.strategy.abstracts.entends.WildDuck; import ltd.huazhongyang.strategy.strategy.interfaces.impl.BadFlyBehavior; import ltd.huazhongyang.strategy.strategy.interfaces.impl.NoQuackBehavior; public class Client { public static void main(String[] args) { WildDuck wildDuck = new WildDuck(); wildDuck.display(); wildDuck.fly(); wildDuck.quack(); PakingDuck pakingDuck = new PakingDuck(); pakingDuck.display(); pakingDuck.fly(); pakingDuck.quack(); PakingDuck pakingDuck1 = new PakingDuck(new BadFlyBehavior(),new NoQuackBehavior()); pakingDuck1.display(); pakingDuck1.fly(); pakingDuck1.quack(); } }
- 测试结果
- 注意事项和细节
- 关键:分析项目中变化部分与不变部分
- 核心思想是:多用组合/聚合 ,少用继承;多用行为类组合,而不是行为的继承,使得更有d性。体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多重转移语句(if…else if…else)提供了可以替换继承关系的办法;策略模式将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使得它易于切换、理解扩展。
- 需要注意的是:每添加一个策略就需要添加一个类,当策略过多是会导致类数目庞大。
- 基本介绍
- 传统方案
- 策略模式在JDK-Arrays应用的源码分析
- JDK中的Arrays的Comparator就使用了策略模式
- 具体实现:
对数组进行排序- 方式一
- 说明:
1.实现了Comparator 接口(策略接口) ,匿名类 对象 new Comparator() {。。。。}
2.对象 new Comparator() {。。。} 就是实现了策略接口的对象
3.public int compare(Integer o1, Integer o2) {} 指定具体的处理方式 - 代码实现:
Integer[] data = {1,9,5,3,4,6,8,7,2}; Comparator
comparator = new Comparator () { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }; //根据策略模式进行排序 Arrays.sort(data,comparator); System.out.println(Arrays.toString(data)); - 测试结果
- sort源码分析
public static
void sort(T[] a, Comparator super T> c) { if (c == null) { sort(a); } else { if (LegacyMergeSort.userRequested) legacyMergeSort(a, c); else TimSort.sort(a, 0, a.length, c, null, 0, 0); } } - 说明:
- 方式二
- 说明:使用Lambda表达式实现策略模式
- 代码实现
Integer[] data1 = {1,9,5,3,6,4,8,7,2}; Arrays.sort(data1,(var1,var2) ->{ return Integer.compare(var1.compareTo(var2), 0); }); System.out.println(Arrays.toString(data1));
- 测试结果
- 方式一
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)