首先是策略模式的定义:策略模式定义了算法族,分别封装了起来,让他们之间能够互相替换,此模式让算法的变化独立于使用算法的顾客。
这里的算法族就是指一个接口和一组实现改接口的类,然后在其它类中,声明这个接口,构造方法中,实例化实现了接口的类,这样,就能实现较低的耦合程度,比如游戏中的武器切换。定义一个武器接口,然后写好多个武器类。都继承这个接口,为了灵活动态切换武器,仅仅要在角色类中写一个setXX(接口)方法就能在执行时改变武器。改变状态。
这样的模式用到了两种设计原则:1.分析对象中变的和不变的属性,把变的属性分离独立出来进行封装。不要和那些不变的代码混在一起。
2.面向接口编程。
书中用了两个样例解释了这个模式,一个是鸭子的样例,不同鸭子有不同的叫法和不同的飞行状态,还有不同的外观。
所以把叫和飞抽出来写成接口,定义了一组算法族。个人认为状态也是能够分离出来的。另一个就是上面说过的枪的样例。
以下是详细的练习代码:
首先是飞能力的算法族:
package fly; public interface FlyBehavior { public void fly(); }
package fly; public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("我不会飞啊啊啊啊"); } }
package fly; public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("我会用翅膀飞"); } }
package quack; public interface QuackBehavior { public void quack(); }
package quack; public class QuackGG implements QuackBehavior { @Override public void quack() { System.out.println("叽叽叫"); } }
package duck; import quack.QuackBehavior; import fly.FlyBehavior; public abstract class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior; public abstract void display(); public void fly() { flyBehavior.fly(); } public void quack() { quackBehavior.quack(); } }一个鸭子模型:
package duck; import quack.QuackBehavior; import quack.QuackGG; import fly.FlyBehavior; import fly.FlyWithWings; public class DuckModel extends Duck { public DuckModel() { flyBehavior = new FlyWithWings(); quackBehavior = new QuackGG(); } @Override public void display() { System.out.println("我是会飞的叽叽鸟"); } }測试:
import duck.DuckModel; public class TestDuck { public static void main(String args[]) { DuckModel dm = new DuckModel(); dm.display(); dm.fly();dm.quack(); } }
总结:使用模式能够使代码更加easy维护。