策略模式也叫政策模式,是一种比较简单的设计模式。它的目的是定义一组算法,将每个算法都封装起来。并且使他们之间可以互换。针对一组算法,将每一个算法封装到具有接口的独立的类中,从而使他们可以相互替换,使得算法可以在不影响到客户端的情况下发生变化。
引入
我们先来看一个示例
// 定义一个抽象类public abstract class Duck {public Duck(){}/*** 显示鸭子信息*/public abstract void display();public void quack() {System.out.println("鸭字嘎嘎叫~");}public void swim(){System.out.println("dack can swim");}public void fly(){System.out.println("dack can fly");}}// 定义北京鸦public class PekingDuck extends Duck{@Overridepublic void display() {System.out.println("Pecking Duck");}/*** 因为北京鸦不能飞翔,所以重写fly方法*/@Overridepublic void fly() {System.out.println("Peking Duck can not fly");}}//定义玩具鸦public class ToyDock extends Duck{@Overridepublic void display() {System.out.println("Tony Duck");}// 玩具鸦不会叫,不会飞,不会游泳。// 所以要重写父类所有方法@Overridepublic void quack() {System.out.println("Tony DUck can not quack");}@Overridepublic void swim() {System.out.println("Tony Duck can not swim");}@Overridepublic void fly() {System.out.println("Tony Duck can not fly");}}
可以看到,北京鸭和玩具鸦都继承了Duck类,所以fly让所有子类都会飞了,这是不正确的。当然,我么可以通过重写方法来解决,但是一个玩具鸦,我们需要重写父类所有的方法的实现,为了解决这种问题,我们使用策略模式。

我们就只写fly这一个功能吧。
/*** 定义一个行为接口*/public interface FlyBehavior {void fly();}// 实现这个接口public class GoodFlyBehavior implements FlyBehavior{@Overridepublic void fly() {System.out.println("飞翔技术高超");}}public class BadFlyBehavior implements FlyBehavior{@Overridepublic void fly() {System.out.println("飞翔技术一般");}}public class NoFlyBehavior implements FlyBehavior{@Overridepublic void fly() {System.out.println("不会飞翔");}}// 定义一个抽象类public abstract class Duck {/*** 属性,策略接口*/FlyBehavior flyBehavior;public Duck(){}/*** 显示鸭子信息*/public abstract void display();public void setFlyBehavior(FlyBehavior flyBehavior){this.flyBehavior = flyBehavior;}public void quack() {System.out.println("鸭字嘎嘎叫~");}public void swim(){System.out.println("dack can swim");}public void fly(){// 对fly进行改进if (flyBehavior != null){flyBehavior.fly();}}}// 不需要自己实现,只需要传入这个行为属性就行了public class PekingDuck extends Duck{@Overridepublic void display() {System.out.println("Pecking Duck");}/*** 假如北京鸭可以飞翔,但是飞翔技术一般*/public PekingDuck(){flyBehavior = new BadFlyBehavior();}}
经过上面的改造,我们甚至可以动态的改变某个对象的行为。
public class Client {
public static void main(String[] args) {
PekingDuck pekingDuck = new PekingDuck();
pekingDuck.fly();
// 动态改变
pekingDuck.setFlyBehavior(new NoFlyBehavior());
pekingDuck.fly();
}
}
