策略模式

来源:互联网 发布:linux 韦东山 编辑:程序博客网 时间:2024/05/29 05:54
今天是学习Headfirst的第一天,第一天学习的策略模式。
书中的例子是鸭子的例子。假如你要设计一个鸭子的类,这个鸭子的基本行为是游泳,但是有些鸭子会飞会叫,有些鸭子不会飞只会叫,比如玩具鸭。在这种情况下,鸭子这个类要如何设计才能显得有弹性,也就是以后就算你要改动,改动的地方也很少。
刚开始可能有人会觉得定义一个抽象类Duck,然后它的子类继承这个类,然后覆盖它的方法,如果这个鸭子不具备这个能力,那就覆盖后什么都不做,例如:
这个Duck为:


那么如果要让实现一只不会叫不会飞的鸭子如下:


这样做的缺点是 每次改变基类它的子类都要随之改变,并且无法进行动态改变鸭子的行为,显然,这样设计出来的系统不是一个弹性的系统。
那么换成用实现接口的方式行不行呢?也就是如图所示:


这个方法有一个最大的缺点就是重复的代码会变多。
对于这个最好的解决方法是把行为单独取出,和Duck类进行分开。


之后在Duck中加入两个实例变量:


此时:perfomQuack()方法如下:


这样我们就可以利用多态来取得我们想要的行为。(这里体现多用组合,少用继承的设计原则
有点乱,看代码就明白了:
首先是两个接口:
public interface FlyBehavior {
 
void fly();
}
public interface QuackBehavior {
 
void quack();
}
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck(){}
public abstract void display();
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
public void swim(){
System.out.println("ALL duck float,even docoys");
}
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}
如果想实现一只会飞会叫的鸭子,只需要这么做:
public class FlyWithWings implements FlyBehavior{
 
public void fly() {
// TODO Auto-generated method stub
System.out.println("I am flying");
}
}
public class Quack implements QuackBehavior{
 
public void quack() {
// TODO Auto-generated method stub
System.out.println("Quack");
}
}
public class MallardDuck extends Duck{
 
public MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display() {
// TODO Auto-generated method stub
System.out.println("I am a real Mallard duck");
}
 
}
接下来 进行测试:
public class MiniDuckSimulator{
 
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.performFly();
mallard.performQuack();
}
}
输出的结果:


如果想改变行为,只需要调用对应的set行为即可。
这样的设计模式就称为策略模式,它的定义如下:
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
这个设计模式体现了以下的设计原则:
a.找出应用中可以需要变化之处,把它们独立出来,不要和那些不需要变化额代码混在一起。
b.针对接口编程,而不是针对实现编程。
c.多用组合,少用继承。

0 0
原创粉丝点击