策略模式
鸭子问题
传统方案解决鸭子问题
传统方案实现代码
package com.strategy; //抽象类 鸭子 public abstract class Duck { public Duck() { } //默认实现 public void quack(){ System.out.println("鸭子嘎嘎叫"); } public void swim(){ System.out.println("鸭子会游泳"); } public void fly(){ System.out.println("鸭子会飞翔"); } //显示鸭子的信息 public abstract void display(); }
package com.strategy; public class PekingDuck extends Duck { @Override public void display() { System.out.println("这是北京鸭"); } @Override public void fly() { System.out.println("北京鸭不能飞翔"); } }
package com.strategy; public class ToyDuck extends Duck { @Override public void display() { System.out.println("这是玩具鸭"); } @Override public void quack() { System.out.println("玩具鸭不能嘎嘎叫"); } @Override public void swim() { System.out.println("玩具鸭不会游泳"); } @Override public void fly() { System.out.println("玩具鸭不会飞翔"); } }
package com.strategy; public class WildDuck extends Duck { @Override public void display() { System.out.println("这是野鸭"); } }
package com.strategy; public class Client { public static void main(String[] args) { Duck pekingDuck = new PekingDuck(); pekingDuck.display(); pekingDuck.fly(); pekingDuck.quack(); pekingDuck.swim(); } }
执行结果:
北京鸭不能飞翔
鸭子嘎嘎叫
鸭子会游泳
这是北京鸭
传统方式解决鸭子问题分析和解决方案
策略模式的基本介绍
策略模式的原理类图
说明:从上图可以看到,客户context,有成员变量strategy或者其他的策略接口,至于需要使用哪个策略,我们可以在构造器中进行指定。
策略模式解决鸭子问题
这里补充一个小知识点哈:
组合:就好比是类中的属性
聚合:就好比是通过构造方法传入参数一样。
使用策略模式代码实现
package com.strategy.improve; //抽象类 鸭子 public abstract class Duck { //属性 策略接口 FlyBehavior flyBehavior; //protected FlyBehavior flyBehavior; //这种写法也是可以的 //其他属性 策略接口 QuackBehavior quackBehavior; public Duck() { } //默认实现 public void quack() { if(null != quackBehavior){ quackBehavior.quack(); } } public void swim() { System.out.println("鸭子会游泳"); } public void fly() { if (null != flyBehavior) { flyBehavior.fly(); } } //显示鸭子的信息 public abstract void display(); public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
package com.strategy.improve; public interface FlyBehavior { public abstract void fly();//子类要具体实现 }
package com.strategy.improve; public class BadFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞翔技术一般"); } }
package com.strategy.improve; public class GoodFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞翔技术高超"); } }
package com.strategy.improve; public class NoFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("不会飞翔"); } }
package com.strategy.improve; public interface QuackBehavior { void quack(); }
package com.strategy.improve; public class GaGaQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("嘎嘎叫"); } }
package com.strategy.improve; public class GeGeQuackBehavior implements QuackBehavior{ @Override public void quack() { System.out.println("咯咯叫"); } }
package com.strategy.improve; public class PekingDuck extends Duck { @Override public void display() { System.out.println("这是北京鸭"); } //构造器 传入FlyBehavior public PekingDuck() { flyBehavior = new NoFlyBehavior(); quackBehavior = new GeGeQuackBehavior(); } }
package com.strategy.improve; public class ToyDuck extends Duck { @Override public void display() { System.out.println("这是玩具鸭"); } @Override public void swim() { System.out.println("玩具鸭不会游泳"); } //构造器 传入FlyBehavior public ToyDuck() { flyBehavior = new BadFlyBehavior(); quackBehavior = new GeGeQuackBehavior(); } }
package com.strategy.improve; public class WildDuck extends Duck { @Override public void swim() { super.swim(); } //构造器 传入FlyBehavior public WildDuck() { flyBehavior = new GoodFlyBehavior(); quackBehavior = new GaGaQuackBehavior(); } @Override public void display() { System.out.println("这是野鸭"); } }
package com.strategy.improve; public class Client { public static void main(String[] args) { WildDuck wildDuck = new WildDuck(); System.out.println("野鸭的特征:"); wildDuck.fly(); wildDuck.quack(); ToyDuck toyDuck = new ToyDuck(); System.out.println("玩具鸭的特征"); toyDuck.fly(); toyDuck.quack(); //动态改变某个对象的行为 玩具鸭子不会飞翔 toyDuck.setFlyBehavior(new NoFlyBehavior()); System.out.println("玩具鸭的实际飞翔情况:"); toyDuck.fly(); } }
运行结果:
野鸭的特征:
飞翔技术高超
嘎嘎叫
玩具鸭的特征
飞翔技术一般
咯咯叫
玩具鸭的实际飞翔情况:
不会飞翔
策略模式的注意事项和细节