引用:http://www.cnblogs.com/wenjiang/archive/2013/02/28/2937623.html
策略模式是设计模式中很重要的一种,它的主要意图就是:定义了算法族,分别封装起来,让它们之间可以互相替换。它让算法的变化可以独立于使用算法的客户,使得我们可以随时更改它们而不影响客户端的代码,而客户端可以自由选择不同的算法执行。
要想了解策略模式,我们就要理解几个重要概念:
public abstract class Plane{ private abstract void fly(); private abstract void attack(); }
接着我们就开始定义一些具体型号的战斗机:
public class FlyMaxPlane extends Plane{ private void fly(){ System.out.println("This plane fly with Rocket"); } private void attack(){ System.out.println("This plane can't attack"); } } public class AttackMaxPlane extends Plane{ private void fly(){ System.out.println("This plane can't fly"); } private void attack(){ System.out.println("This plane attack with Rocket"); } }
然后就在我们的程序中这样写:
public static void main(String[] args){ FlyMaxPlane plane1 = new FlyMaxPlane(); AttackMaxPlane plane2 = new AttackMaxPlane(); showFunctionOfPlane(plane1); showFunctionOfPlane(plane2); } private void showFunctionOfPlane(Plane plane){ plane.fly(); plane.attack(); }
使用继承可以解决这个问题,但是,继承也有它自己的问题。继承最大的问题就是,基类的改变会传给所有的子类,这是我们类设计者不想看到的。那么,不使用继承不就可以了?接口,就是我们这种情况下最好的替代方案。
public Interface Plane{ void fly(); void attack(); }
这样就将具体的实现交给实现类,从而避免我们上面的问题。确实如此,但不同型号的战斗机,就算外观差距太大,基本的东西都是不变的,像是重量这些基本的属性,至少在很长的一段时间都不会发生变化,如果用接口的话,我们就不能设置一些共同的属性和方法,当然我们可以将这样的东西交给实现类来实现,这样,代码重复的程度太可怕了!
public Interface FlyAble{ void fly(); } public Interface AttackAble{ void attack(); }
public class FlyMaxPlane extends Plane implements FlyAble, AttackAble{ void fly(){} void attack(){} } public class AttackMaxPlane extends Plane implements FlyAble, AttackAble{ void fly(){} void attack(){} }
为什么会这样写?很简单,因为我们可能有些飞机根本不具有飞行能力,像是这样:
public class NotFlyPlane extends Plane implements AttackAble{ void attack(){} }
但是,根本不需要我们的子类实现这些接口,接口更大的意义是对象组合,这样根本就失去了接口的优点。要想利用接口的这些优点,我们可以这样建立这两个接口的实现类组,像是这样:
public class FlyMax implements FlyAble{ void fly(){} } public class AttackMax implements AttackAble{ void attack(){} }
然后再在我们的代码中使用这些实现类:
public class FlyMaxPlane extends Plane{ FlyMax = new FlyMax(); FlyMax.fly(); }
这就是使用对象组合的方式,但是这样的方式还不够优雅。这时,策略模式就正式登场了,因为它就是处理对象组合的一种模式。
public class BehaviorChange{ private FlyAble fly; private AttackAble attack; private void setFly(FlyAble fly){ this.fly = fly; } private void setAttack(AttackAble attack){ this.attack = attack; } private void execute(){ fly.fly(); attack.attack(); } }
接着再在我们的子类中使用这个委托类:
public class FlyMaxPlane extends Plane{ public static void main(String[] args){ BehaviorChange behaviorChange = new BehaviorChange(); behaviorChange.setFly(new FlyMax()); behaviorChange.execute(); } }
behaviorChange.setFly(new FlyMin());