说明:以下内容是学习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