java设计模式之策略模式

最近学习了设计模式方面的一些知识,感觉设计模式真的太重要了,深感之前写的代码就是渣啊,只是为了实现功能,一点复用性都没有,都是一次性代码,这个以后要改。

问题:以鸭子为例,我们关心它的几个属性:叫、吃、飞、外观。所有的鸭子都会叫、吃,但是并不是所有的鸭子都会飞,外观都有,但不同种类不一样。我们就简单设计A、B、C...类表示。

第一种方式:

 1 public class ADuck{
 2     public void sing(){
 3         System.out.println("gua gua...");
 4     }
 5     public void eat(){
 6         System.out.println("I love fish.");
 7     }
 8     public void color(){
 9         System.out.println("I am black.");
10     }
11 }
12 public class BDuck{
13     public void sing(){
14         System.out.println("gua gua...");
15     }
16     public void eat(){
17         System.out.println("I love grass");
18     }
19     public void color(){
20         System.out.println("I am yellow");
21     }
22 }

这种方式就是典型的一次性代码。第二种实现方式:

 1 public class Duck{
 2     public void sing(){
 3         System.out.println("gua gua...");
 4     }
 5     public abstract void eat();
 6     public abstract void color();
 7 }
 8 
 9 public class ADuck extends Duck{
10     public void eat(){
11         System.out.println("I love fish.");
12     }
13     public void color(){
14         System.out.println("I am black");
15     }
16 }

BDuck实现同理,这样就把功能相同的代码写在基类里,子类实现不一样的代码,从而实现了代码的复用。但是,这还是不够好的。

如果此时有了新需求,要加一个飞的功能。那么我们只能向下面这样在基类中添加了,不会飞的不实现该功能即可:

public class Duck{
    public void sing(){
        System.out.println("gua gua...");
    }
    public abstract void eat();
    public abstract void color();
    public abstract void fly();
}

public class ADuck extends Duck{
    public void eat(){
        System.out.println("I love fish.");
    }
    public void color(){
        System.out.println("I am black.");
    }
    public void fly(){
        System.out.println("I can fly.");//不会飞的该方法为空,不实现
    }
}

这样好像是能解决我们的问题,但是每次有新的需求都要修改基类,耦合太高,好像不是一个好的解决方式。

我们继续改进,把fly()方法放在一个接口里面,会飞的就继承该接口,不会飞的不继承即可。

 1 public interface IFly{
 2     public void fly(); 
 3 }
 4 public class Duck{
 5     public void sing(){
 6         System.out.println("gua gua...");
 7     }
 8     public abstract void eat();
 9     public abstract void color();
10 }
11 public class ADuck extends Duck implements IFly{
12     public void eat(){
13         System.out.println("I love fish.");
14     }
15     public void color(){
16         System.out.println("I am black.");
17     }
18     public void fly(){
19         System.out.println("I can fly.");
20     }
21 }
22 public class BDuck extends Duck{
23     public void eat(){
24         System.out.println("I love grass.");
25     }
26     public void color(){
27         System.out.println("I am yellow.");
28     }
29 }

这样感觉好多了,但是接口并不会有具体实现,也就是不能复用,只能在每个继承的基类中具体去实现,那么就要用到策略模式了。

public interface FlyBehavior{
    public void fly();
}
public interface EatBehavior{
    public void eat();
}
public class FlyByWing implements FlyBehavior{
    public void fly(){
        System.out.println("I fly with my wings");
    }
}
public class FlyNoWay implements FlyBehavior{
    public void fly(){
        System.out.println("I can not fly.");
    }
}
public class EatFish implements EatBehavior{
    public void eat(){
        System.out.println("I eat fish.");
    }
}
public class EatGrass implements EatBehavior{
    public void eat(){
        System.out.println("I eat grass.");
    }
}
public class Duck{
    private FlyBehavior flyBehavior;
    private EatBehavior eatBehavior;
    public Duck{};
    public void setFlyBehavior(FlyBehavior flyBehavior){
        this.flyBehavior=flyBehavior;
    }
    public void setEatBehavior(EatBehavior eatBehavior){
        this.eatBehavior=eatBehavior;
    }
    public void sing(){
        System.out.println("gua gua...");
    }
    public abstract void color();
    public void fly(){
        flyBehavior.fly();
    }
    public void eat(){
        eatBehavior.eat();
    }
}
public class ADuck extends Duck{
    public ADuck(FlyBehavior flyBehavior,EatBehavior eatBehavior){
        this.setFlyBehavior(flyBehavior);
        this.setEatBehavior(eatBehavior);
    }
    public void color(){
        System.out.println("I am black.");
    }
}

上面的代码有什么好处呢,我们实现了多个继承自同一个接口的功能类,并且这些功能类与下面的具体类没有继承关系,耦合性非常低,而且这些功能我们在别的地方还可以复用,比如吃的功能,是动物类都会有的,是可以重复利用的。

posted @ 2013-09-08 12:48  楠楠IT  阅读(231)  评论(0编辑  收藏  举报