Head First 设计模式-策略者模式20170321

本人是Head First的书迷,最近刚入手设计模式一书,学习了策略者模式,与大家分享。

BOb的公司开发了一款模拟鸭子的游戏(SimDuck),游戏中的各种鸭子会戏水,呱呱叫。该系统内部设计使用了标准的OO技术,设计了一个鸭子超类。

    ?public class Duck{

    ?    ?quack();

    ?    swim();

}

随着公司业务的发展,现在需要把鸭子设计的可以飞起来。1.首先我们想到的解决方式就是在超类中加入fly()方法,其他的鸭子类继承超类就可以了。但是这就会导致一些问题,让本来就不会飞的鸭子也继承该类,就会有设计缺陷,就算是重写fly()方法,让该方法什么都不做,也会造成大量的代码冗余。2.利用接口如何?可以把fly()从超类中抽取出来,放进一个Flyable接口中,这样一来,只有会飞的鸭子才实现此接口,这虽然是一个不错一的方法,至少不会再有会飞的橡皮鸭(橡皮鸭不会飞),但是却造成代码无法复用,无论什么时候修改某个行为(比如修改接口中一个方法的返回值类型),必须得往下追踪并在每一个定义次行为的类中修改它,不小心,可能会造成新的错误。

这时候我们就需要一种设计模式来解决该问题,虽然会增加代码量(因为Java本来就是把小型项目开发成中型项目,把中型项目开发成大型项目,但是会易于我们后期的维护等一系列行为)。首先我们必须明白一个设计原则,就是把每次来需求会发生改变的代码抽取出来,和其他稳定的代码有所区分。

就我们这个例子来说,我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变。为了要把这两个行为从Duck类中分开,将它们从Duck类中取出来,建立一组新类来代表每个行为。

设计鸭子的行为,我们希望一切能有弹性,我们可以动态的改变鸭子的行为。接着来看我们的第二个设计原则:针对接口编程,而不是针对实现编程。

我们利用接口代表每个行为,如FlyBehavior与QuackBehavior,而行为的每个实现都将实现其中的一个接口。所以这次鸭子类不会负责实现Flying与Quacking接口,反而是由我们制造一组其他类专门实现FlyBehavior与QuackBehavior,这就称为“行为”类。在我们新的设计中,鸭子的子类将使用接口(FlyBehavior)所表示的行为,所以实际的“实现”不会被绑死在鸭子的子类中(其实就是具体的编码写在了实现的FlyBehavior和QuackBehavior的类中)。

整合鸭子的行为。现在是鸭子会将飞行和呱呱叫的动作“委托”(delegate)别人处理,而不是定义在Duck类或子类的内的方法了。做法是这样的,首先在Duck类中“加入两个实例变量”,分别为“flyBehavior”与“quackBehavior”,声明为接口类型。

2.现在我们来实现performQuack();

public class Duck{

    QuackBehavior quackBehavior;

    public void performQuack(){

        quackBehavior.quack();

    }

}

想要进行呱呱叫的动作,Duck对象只要叫quackBehavior对象去呱呱叫就可以了。在这部分代码中,我们不在乎quackBehavior接口对象到底是什么,我们只关心该对象知道如何呱呱叫就够了。

3.我们现在来关心如何设定quackBehavior和flyBehavior的实例变量。

public class MallardDuck extends Duck{

        public MallardDuck(){

    //绿头鸭使用Quack类处理呱呱叫,所以当performQuack()被调用时,该职责被委托给Quack对象

            quackBehavior=new Quack();

            flyBehavior=new FlyWithWings();

        }

}

关于在构造方法中注入对象,我们会在后续的模式中修正。总之我们要明白为什么要有这个设计模式,由于是第一次发,电脑上没有UML图的画图工具(用代码简单说明),后续一定补上。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值