设计模式之策略模式

——学习《Head First 设计模式》,边学边实践。

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

例子:我们要用程序模拟鸭子的行为,有多种鸭子,它们可以呱呱叫,可以飞(飞的不远也是飞。。。),可以游泳等。我们要实现两种不同的鸭子,普通鸭子和橡皮鸭,并让它们具有符合各自特征的行为。

那么,首先写一个父类鸭子类,两种鸭子都可以继承它。我们让鸭子类实现上面三种行为。

public class Duck {

    QuackBehavior quackBehavior;
    FlyBehavior flyBehavior;

    public void performQuack() {
        quackBehavior.quack();
    }
    public void performFly() {
        flyBehavior.fly();
    }
    public void swim() {
        System.out.println("All duck can swim!");
    }

}

上面的代码中,有个QuackBehavior类和FlyBehavior类,这两个类分别表示鸭子鸣叫和飞行,在这里用作成员变量。游泳的行为因为两种鸭子都可以游,所以用一个swim()方法直接实现。

看看QuackBehavior类和FlyBehavior类,两个都是抽象类:

public interface QuackBehavior{
    void quack();
}
public interface FlyBehavior{
    void fly();
}

下面实现一下这两个抽象类,用于表示鸭子具体鸣叫和飞行的行为:

首先是普通鸭子的鸣叫和飞行行为:

public class NormalQuack implements QuackBehavior {
    public void quack() {
        System.out.println("Normal quack! gua gua gua...");//呱呱叫
    }
}
public class NormalFly implements FlyBehavior {
    public void fly() {
        System.out.println("Normal fly!");
    }
}

下面是橡皮鸭子的鸣叫和飞行:

public class RubberQuack implements QuackBehavior {
    public void quack() {
        System.out.println("Rubber quack! Bi Bi Bi...");//哔哔叫
    }
}
public class FlyNoWay implements FlyBehavior {
    public void fly() {
        System.out.println("fly no way!");//橡皮鸭子不会飞
    }
}

接下来该怎么实现呢?

我们实现一下普通鸭子:

public class NormalDuck extends Duck {

    public NormalDuck() {
        flyBehavior = new NormalFly();
        quackBehavior = new NormalQuack();
    }
}

我们让普通鸭子继承了鸭子类,并在构造方法中对继承的两个表示鸭子行为的成员变量赋予了具体的值,这样,普通鸭子是怎样的行为就确定了。

橡皮鸭子同理,但由于橡皮鸭子游泳非常厉害,我们覆盖一下父类的swim()方法:

public class RubberDuck extends Duck {
public RubberDuck(){
    flyBehavior = new FlyNoWay();
    quackBehavior = new RubberQuack();
}

public void swim(){
    super.swim();
    System.out.println("And BubberDuck swims very well!");
}
}

好了,普通鸭子和橡皮鸭子都已经实现了。

我们写个测试程序看看效果:

public class Test {

    public static void main(String[] args) {
        Duck redDuck = new NormalDuck();
        Duck rubberDuck = new RubberDuck();

        redDuck.performQuack();
        redDuck.performFly();
        redDuck.swim();
        System.out.println("---------------------------");
        rubberDuck.performQuack();
        rubberDuck.performFly();
        rubberDuck.swim();
    }
}

输出结果:

Normal quack! gua gua gua...
Normal fly!
All duck can swim!
---------------------------
Rubber quack! Bi Bi Bi...
fly no way!
All duck can swim!
And BubberDuck swims very well!

OK,从结果看,普通鸭子和橡皮鸭子都各自的行为都是正常的。
以上的策略模式实现中,对象的组合起到了重要作用。如果我们把鸭子会有所变化的行为(鸣叫和飞行)也像swim()那样用方法继承去实现的话,当鸭子的某个行为发生变化时,就要检查所有的子类并做修改。比如说,某天一部分种类的鸭子特征发生了改变,不会游泳了,那么如果鸭子子类多达几十种的话,修改swim()将会是十分麻烦的事。而我们用对象的组合实现就会易解决的多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值