您的位置:首页 > 其它

设计模式深入浅出-----策略模式(Strategy Pattern)

2017-07-02 22:46 218 查看
使用模式最好的方式是把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用他们。

策略模式(StrategyPattern):

定义算法族,分别封装起来,让他们之间可以相互替换。此模式让算法的变化独立于使用算法的客户。



1、先从简单的模拟鸭子应用做起:

(1)设计一个鸭子超类,让各种鸭子继承这个超类。





这个是用继承来实现的,看上去没有什么不妥。

(2)现在需要为鸭子增加飞(fly)的功能,而且还会新增鸭子。



只需在父类中加上fiy()方法。橡皮鸭子不会叫,也不会飞,这时只需要覆盖掉里面的方法,让其什么也不做。看上去是很好的设计。

(3)现在设计有变,需要新增100只鸭子,其中很多鸭子不会游泳,也不会飞。

问题:如果用继承,那么你需要自己动手一个个来覆盖,这样的设计还是好的设计吗?

(4)尝试改变设计:将 fly( ) 方法从超类中取出来,放进Flyable接口中去,这样只有会飞的鸭子才实现Flyable接口。

看起来好像是不错的设计,但是并没有做到代码的复用。当有100个鸭子会飞时,那么就必须得实现100次接口了。这只是从一个噩梦跳向另一个噩梦。

2、策略模式引路:

软件开发不变的真理--------CHANGE

不管当初软件设计的多好,一段时间之后,总是需要成长和改变的,否则软件就会死亡。驱动改变的因素很多。

设计原则:找出应用中可能变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。



我们想要的是行为具有弹性。于是可以让鸭子的行为在运行时动态的改变。

设计原则:针对接口编程,而不是实现编程。



现在鸭子的 fiy 与 quack 行为被封装起来了。

现在来写一些代码。

测试代码Duck.Java

[java] view
plain copy

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

[java] view
plain copy

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行为:

[java] view
plain copy

public interface FlyBehavior {   

public void fly();  

}  

[java] view
plain copy

public class FlyNoWay implements FlyBehavior {   

public void fly() {  

System.out.println("I can't fly");  

}  

}  

[java] view
plain copy

public class FlyWithWings implements FlyBehavior {   

public void fly() {  

System.out.println("I'm flying!!");  

}  

}  

[java] view
plain copy

public class FlyRocketPowered implements FlyBehavior {   

public void fly() {  

System.out.println("I'm flying with a rocket");  

}  

}  

测试类:

[java] view
plain copy

publicclass MiniDuckSimulator1 {  

publicstatic void main(String[] args) {  

Duck model = new ModelDuck();  

model.performFly();  

model.setFlyBehavior(newFlyRocketPowered());  

model.performFly();  

}  

设计原则:多用组合,少用继承。

可以看到鸭子的行为不是继承来的,而是和适当的行为对象组合而来的。这种做法会使系统的弹性更大。



以上看到的就是策略模式了。

 定义算法族,分别封装起来,让他们之间可以相互替换。此模式让算法的变化独立于使用算法的客户。



策略模式的一般画法。



HeadFirst系列经典例子呀。

转载请注明出处 http://blog.csdn.net/xn4545945
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: