使用模式最好的方式是把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用他们。
策略模式(StrategyPattern):
定义算法族,分别封装起来,让他们之间可以相互替换。此模式让算法的变化独立于使用算法的客户。
1、先从简单的模拟鸭子应用做起:
(1)设计一个鸭子超类,让各种鸭子继承这个超类。
这个是用继承来实现的,看上去没有什么不妥。
(2)现在需要为鸭子增加飞(fly)的功能,而且还会新增鸭子。
只需在父类中加上fiy()方法。橡皮鸭子不会叫,也不会飞,这时只需要覆盖掉里面的方法,让其什么也不做。看上去是很好的设计。
(3)现在设计有变,需要新增100只鸭子,其中很多鸭子不会游泳,也不会飞。
问题:如果用继承,那么你需要自己动手一个个来覆盖,这样的设计还是好的设计吗?
(4)尝试改变设计:将 fly( ) 方法从超类中取出来,放进Flyable接口中去,这样只有会飞的鸭子才实现Flyable接口。
看起来好像是不错的设计,但是并没有做到代码的复用。当有100个鸭子会飞时,那么就必须得实现100次接口了。这只是从一个噩梦跳向另一个噩梦。
2、策略模式引路:
软件开发不变的真理--------CHANGE
不管当初软件设计的多好,一段时间之后,总是需要成长和改变的,否则软件就会死亡。驱动改变的因素很多。
设计原则:找出应用中可能变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
我们想要的是行为具有弹性。于是可以让鸭子的行为在运行时动态的改变。
设计原则:针对接口编程,而不是实现编程。
现在鸭子的 fiy 与 quack 行为被封装起来了。
现在来写一些代码。
测试代码Duck.java:
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void setFlyBehavior (FlyBehavior fb) {
flyBehavior = fb; //能动态设置飞行行为
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;//能动态设置叫的行为
}
abstract void display();
public void performFly() {
flyBehavior.fly(); //这里是委托, 将fly的行为委托给具体的fly行为
}
public void performQuack() {
quackBehavior.quack();//这里是委托, 将quack的行为委托给具体的quack行为
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
}
Duck的子类ModelDuck.java
public class ModelDuck extends Duck {
//现在要给具体的鸭子类添加行为,只需要在构造方法中实例化具体行为即可。并不需要继承,覆盖。
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Quack(); //quack行为这里没有写出,参照fly行为。
}
public void display() {
System.out.println("I'm a model duck");
}
}
fly行为:
public interface FlyBehavior {
public void fly();
}
public class FlyNoWay implements FlyBehavior {
public void fly() {
System.out.println("I can't fly");
}
}
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("I'm flying!!");
}
}
public class FlyRocketPowered implements FlyBehavior {
public void fly() {
System.out.println("I'm flying with a rocket");
}
}
测试类:
publicclass MiniDuckSimulator1 {
publicstatic void main(String[] args) {
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(newFlyRocketPowered());
model.performFly();
}
设计原则:多用组合,少用继承。
可以看到鸭子的行为不是继承来的,而是和适当的行为对象组合而来的。这种做法会使系统的弹性更大。
以上看到的就是策略模式了。
定义算法族,分别封装起来,让他们之间可以相互替换。此模式让算法的变化独立于使用算法的客户。
策略模式的一般画法。
HeadFirst系列经典例子呀。
转载请注明出处 http://blog.csdn.net/xn4545945