前言

爱因斯坦说过这样一句话:如果你不能简单地解释一样东西,说明你没真正理解它。(ps:如果爱因斯坦没说过,那可能是鲁迅说的......)所以,我写不出这篇文章。我就不打算再学下去,我要继续学策略模式,指导能简单地解释它。

策略模式定义

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

例子

假如现在要做一款鸭子应用,作为一个OO程序员,这可不是一件难事。设计一个鸭子超类,再让它有'呱呱'叫、游泳的方法。

public class Duck{
    public void quck(){ // some code }
    public void swim(){ // some code }
    //other function...
} 

然后让什么可达鸭、唐老鸭去继承超类。接着我们要做一件有趣的事,让鸭子会飞。在Duck类上加 fly() 方法。但是可怕的问题发生了......所有鸭子会飞了,包括'橡皮鸭'也在飞,而且诱饵鸭不会叫也不会飞。这可不是我们希望看到的。

利用接口如何?

把'飞'、'呱呱叫'分离出来分别做成Flyable接口跟Quackable接口。但是java接口不具有实现代码的功能。难道还要给每个角色都去实现飞的功能,这样做就没有使代码达到"复用"的效果。

该怎么做呢?!

先让我们回顾下‘策略’的定义 ,“...让算法的变化独立于使用算法的客户”。我们把'飞'啊、'呱呱叫'啊独立开来,只留下不需要变化的。做成一些行为接口,然后让Duck类用过行为类的类型。

public interface FlyBehavior{
    fly();
}

//会飞的行为类
public class FlyWithWings implements FlyBehavior ()
{
    public void fly()
    {
        System.out.println("i can flying...");
    }
}

//不会飞的行为类
public class FlyNoWay  implements FlyBehavior ()
{
    public void fly()
    {
       //nothing to do,can't fly
    }
}
public interface QuckBehavior{
    quack();
}

//呱呱叫行为类
public class Quack
{
    //实现呱呱叫
}

public class Squeak
{
    //橡皮鸭吱吱叫
}

//不会叫的...

现在我们将飞、叫delegate(委托)别人处理,而不是定义在Duck类中或者子类中。接着我们整理下代码。

public abstract class Duck
{
    FlyBehavior flyBehavior;
    QuckBehavior quckBehavior;
    
    public void performFly()
    {
        flyBehavior.fly();
    }
    
    public void performQuck()
    {
        quckBehavior.quack();
    }
}

写在后面的

让我们再次回归定义,“定义了算法族,分别封装起来”,在这个例子中就是飞的行为、叫的行为。“让算法的变化独立于使用算法的客户”,客户需要一个会飞的鸭子就实现飞接口再实现飞的方法。需要叫就同理,这样去独立于使用算法。

我写得哪里不好,请大神说出来,我会改正的。

 


朕有一个梦
314 声望2 粉丝

Fake it until you become it.