设计模式之策略模式

来源:互联网 发布:蛇口招商网络宽带上班 编辑:程序博客网 时间:2024/06/08 07:21

先从一个简单的鸭子应用说起:

我们定义了一个鸭子超类,并让各种鸭子继承此超类。

abstract class Duck{public void quack(){System.out.println("呱呱叫");}public void swim(){System.out.println("游泳");}public abstract void display();//显示鸭子的外观}class MallardDuck extends Duck{public void display(){System.out.println("外观是绿头");}}class RedheadDuck extends Duck{public void display(){System.out.println("外观是红头");}}
如果我们想让鸭子会飞,则只需要在基类添加fly()方法即可。但是问题来了,不是所有的鸭子都会飞,也不是所有的鸭子都会呱呱叫,例如玩具鸭子。我们可能会想到继承基类,然后重写fly()和quak(),但代码会变多,如果子类变多,则修改起来很麻烦,而且不利于维护。

利用继承来提供Duck的行为,会导致: 

1. 代码在多个子类中重复。2. 很难知道鸭子的所有行为。3.运行时的行为无法改变。4.改变会牵一发而动全身,造成其他鸭子步想要的改变。


利用接口呢? 设置Flyable和Quackable接口,让子类实现它,这似乎可以解决部分的问题,但是却造成代码无法复用,我们还是需要在其子类中实现各种fly(),quack()。因此这不是解决问题的办法。

从哪里开始呢,我们知道,除了fly()和quack()之外,Duck还算正常,没有太大的地方需要修改,因此我们可以考虑将应用中变化的部分独立出来,不要和那些不需要变化的代码混在一起,因为那些不需要变化的代码可以直接实现复用,变化的代码可以通过间接地方法实现复用。

回到鸭子的问题,我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变,因此我们可以将鸭子的这两个行为从Duck中分离出来,建立一组新类来代表每个行为。



使用了新设计,如果我们想加上一个火箭动力行为个一个鸭子 让它可以飞,就可以直接建立一个FlyWithRocket类实现Flyable接口,是不是耦合性大大降低了呢,修改和维护起来更加方便了呢。

但是现在还没完,我们还需要将行为类整合到鸭子类中,这里就用到了组合的概念。我们在鸭子的基类中添加 FlyBahavior和QuackBehavior的对象,针对接口编程,实现不同子类方法的多态访问。

贴上代码,供参考:

<span style="font-size:14px;">interface FlyBehavior{public void fly();}interface QuackBehavior{public void quack();}class FlyWithWings implements FlyBehavior{public void fly(){System.out.println("用翅膀飞");}}class FlyNoWay implements FlyBehavior{public void fly(){System.out.println("不会飞");}}class SqueakQuack implements QuackBehavior{public void quack(){System.out.println("吱吱叫");}}class NoWayQuack implements QuackBehavior{public void quack(){System.out.println("不会叫");}}abstract class Duck{FlyBehavior flyBehavior;QuackBehavior quackBehavior;public void swim(){System.out.println("游泳");}public abstract void display();//显示鸭子的外观public void performFly(){flyBehavior.fly();}public void performQuack(){quackBehavior.quack();}}class MallardDuck extends Duck{public MallardDuck(){flyBehavior = new FlyWithWings();quackBehavior = new SqueakQuack();}public void display(){System.out.println("外观是绿头");}}public class DuckTest{public static void main(String[] args){Duck mallardDuck = new MallardDuck();mallardDuck.performFly();mallardDuck.performQuack();}}</span>
同样如果你想对Duck的行为进行改变,可以在Duck类写上SetFlyBehavior(FlyBehavior flyBehavior)和SetQuackBehavior(QuackBehavior quackBehavior)

为了策略模式下定义,我们可以把鸭子的行为看成是“一族算法”。

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



0 0
原创粉丝点击