说明:以下内容是学习Head First后自行整理的笔记。内容和程序均来自于该书
策略模式:定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
概念理解起来生硬,下面用一个鸭子的例子说明。
有一个模拟鸭子的游戏。游戏中有各种各样的鸭子,它们可以游泳,呱呱叫。按照之前的设计一般是这样的:有一个鸭子的超类Duck,有swim、quack的方法,然后不同的鸭子类去继承它。
这个时候多了一个需求,要让鸭子会飞,很自然你会在Duck里面去加一个fly方法。
仔细想一想这种设计思路,是不是会存在问题。
1、如果你在Duck里对fly等方法做了实现,这个时候会出现问题,那就是并不是所有的鸭子都是会飞的,比如只有野鸭子会飞,橡皮鸭并不会飞。
2、当然你会说我会把实现放到子类中,超类并不做实现。那么另一个问题自然会出现,那就是如果野鸭子跟水鸭子都是会飞的,而且都是一样的飞法,那fly这个方法不就会被写了两次甚至跟多,这样是不利于维护的。而且如果游戏中有另一个类:鹅,它也是会飞的,那就更加麻烦了。
所以这个时候策略模式就发挥作用了
下图是设计的思路
下面是代码
Duck.java
package bean; public abstract class Duck { public Duck(){}; FlyBehavior flyBehavior; QuackBehavior quackBehavior; public FlyBehavior getFlyBehavior() { return flyBehavior; } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public QuackBehavior getQuackBehavior() { return quackBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void swim(){ System.out.println(); } public void fly(){ flyBehavior.fly(); } public void quack(){ quackBehavior.quack(); } }
FlyBehavior.java
package bean; public interface FlyBehavior { public void fly(); }
FlyWithWings.java
package bean; public class FlyWithWings implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("I fly with wing!"); } }
FlyNoWay.java
package bean; public class FlyNoWay implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can‘t fly"); } }
QuackBehavior.java
package bean; public interface QuackBehavior { public void quack(); }
QuackGaGa.java
package bean; public class QuackGaGa implements QuackBehavior { @Override public void quack() { // TODO Auto-generated method stub System.out.println("ga ga"); } }
QuackNoWay.java
package bean; public class QuackNoWay implements QuackBehavior { @Override public void quack() { // TODO Auto-generated method stub System.out.println("I can‘t quack"); } }
CleverDuck,java
package bean; public class CleverDuck extends Duck { public CleverDuck(){ this.flyBehavior = new FlyWithWings(); this.quackBehavior = new QuackGaGa(); } }
StupidDuck.java
package bean; public class StupidDuck extends Duck { public StupidDuck(){ this.flyBehavior = new FlyNoWay(); this.quackBehavior = new QuackNoWay(); } }
设计原则:
1、针对接口编程,而不是针对实现编程(这个很好理解)
2、多用组合,少用继承。(如本例中,鸭子的行为不是靠继承得来的,而是通过行为对象的“组合”得来的,这让程序更加的灵活)
原文地址:http://1531439090.blog.51cto.com/6088789/1652069