设计模式之策略模式:定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
设计原则:
(1)找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
(2)针对接口编程,而不是针对实现编程
(3)多用组合,少用继承
使用组合建立的系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态的改变行为”,只要组合的行为对象符合正确的接口标准即可。
package 策略模式; /** * 鸭子现在会将飞行和呱呱叫的动作“委托”别人处理,而不是使用定义在Duck类内的呱呱叫和飞行方法 * */ public abstract class Duck { /** * 首先,在Duck类中加入两个实例变量,分别为flyBehavior,quackBehavior,声明为接口类型, * 每个鸭子对象都会动态的设置这些变量,以在运行时引用正确的行为类型。 * * 每只鸭子都会实现FlyBehavior和QuackBehavior接口对象 * */ FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() { // TODO Auto-generated constructor stub } public abstract void dispaly(); /** * 鸭子对象不会亲自处理飞行和呱呱叫行为,而是委托给flyBehavior和quackBehavior引用的对象 * */ public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println("All "); } public void setFlyBehavior(FlyBehavior fb) { flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; } }
package 策略模式; /** * 所有飞行类都必须实现的接口 * */ public interface FlyBehavior { public void fly(); }
package 策略模式; /** * 所有叫声类都必须实现的接口 * */ public interface QuackBehavior { void quack(); }
package 策略模式; /** * 这是飞行类的实现。给不会飞行的鸭子使用 * */ public class FlyNoWay implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("我不能飞"); } }
package 策略模式; /** * 火箭飞行方式 * */ public class FlyRocketProwered implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("我能用火箭飞行"); } }
package 策略模式; /** * 这是飞行类的实现。给会飞行的鸭子使用 * */ public class FlyWithWings implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("我能飞"); } }
package 策略模式; /** * 叫声类实现 * */ public class Quack implements QuackBehavior { @Override public void quack() { // TODO Auto-generated method stub System.out.println("呱呱叫"); } }
package 策略模式; /** * 叫声类实现 * */ public class Squeak implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("吱吱叫"); } }
package 策略模式; /** * 叫声类实现 * */ public class MuteQuack implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("不会叫"); } }
package 策略模式; /** * 绿头鸭 * * * */ public class MallardDuck extends Duck{ /** * 绿头鸭使用Quack类处理呱呱叫,所以当performQuack()被调用时,叫的职责委托给Quack对象,而我们将得到真正的呱呱叫。 * */ public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } @Override public void dispaly() { // TODO Auto-generated method stub System.out.println("MallardDuck"); } }
package 策略模式; /** * 模型鸭 * */ public class ModelDuck extends Duck { public ModelDuck() { // TODO Auto-generated constructor stub flyBehavior = new FlyNoWay(); quackBehavior = new Squeak(); } @Override public void dispaly() { // TODO Auto-generated method stub System.out.println("我是模型鸭"); } }
package 策略模式; public class MiniDuckSimulator { public static void main(String[] args) { Duck mallard = new MallardDuck(); /** * 这会调用MallardDuck()继承来的方法,进而委托给给对象的QuackBehavior和FlyBehavior对象处理 * */ mallard.performQuack(); mallard.performFly(); System.out.println("------------------------"); /** * 模型鸭 * */ Duck model = new ModelDuck(); model.performQuack(); model.performFly(); /** * 设置不同的飞行方式 * */ model.setFlyBehavior(new FlyRocketProwered()); model.performFly(); } }