策略模式指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。(来自百度百科)
策略模式的本质是:分离算法,选择实现。
问题:如何让一只玩具鸭子飞起来?
答:给这只鸭子装上火箭。
思考:鸭子类具有飞行的能力,玩具鸭是鸭子的子类,但是不具备飞行的能力,所以需要重写飞行的飞行方法。
假设:如果,我们不将飞行看成鸭子的一个方法,而是看成一个行为接口(QuackBehavior quackBehavior;) * 各种鸭子继承鸭子类后,实现不同的行为接口,就具有了各式各样的行为了。
1,鸭子抽象类,鸭子具有表现声音和飞行的能力,具体的表现取决于声音和飞行的行为,由具体实现类决定使用哪种行为
public abstract class Duck { QuackBehavior quackBehavior; //鸭子叫的行为, FlyBehavior flyBehavior; //飞行的行为 public Duck() { } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public abstract void display(); public void performQuack(){ quackBehavior.quack(); } public void performFly(){ flyBehavior.fly(); } }
2,野鸭子,继承鸭子抽象类
public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } public void display(){ System.out.println("I am a real Mallard duck"); } }
3,模型鸭,继承鸭子抽象类
public class ModelDuck extends Duck { public ModelDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); } @Override public void display() { System.out.println("I am a ModelDuck"); } }
4,行为接口,鸭子叫和飞行接口
public interface FlyBehavior { void fly(); }
public interface QuackBehavior { void quack(); }
5,鸭子叫接口实现类
1)正常呱呱叫
public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("真的呱呱叫"); } }
2)吱吱叫
public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("吱吱叫"); } }
3)不会叫的
public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("不会叫"); } }
6,飞行接口实现类
1)正常用翅膀飞
public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("振翅高飞"); } }
2)用火箭飞
public class FlyRocketPowered implements FlyBehavior { @Override public void fly() { System.out.println("I am fly with a rocket"); } }
3)不会飞
public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("不会飞"); } }
7,让模型鸭飞起来
public class MiniDuckSimulator { public static void main(String[] args) { Duck model = new ModelDuck(); //新建一个模型鸭 model.display(); model.performFly(); //尝试飞行 model.setFlyBehavior(new FlyRocketPowered()); //将飞行策略更换 model.performFly(); //再次尝试飞行 } }
8,结果
I am a ModelDuck
不会飞
I am fly with a rocket
Process finished with exit code 0
缺点:
1,需要知道所有的策略类,并自行决定使用哪一个策略类。
2,策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。