Head First 设计模式总结(一)策划者模式

本文对《Head First 设计模式》中的策划者模式进行了总结

策划者模式

问题描述: 一款模拟鸭子游戏,要求运行时能产生各种不同的鸭子(绿头鸭子,红头鸭子,橡皮鸭子),现在要求一部分鸭子具备飞行功能。

错误的做法1:

一个公司程序员采用了继承的方法,让所有鸭子继承超类Duck,然后在Duck中加上了fly(),swim(),quack()等方法,产生了可怕的结果,(橡皮鸭会飞了)。这使得一些鸭子具备了一些他们不需要的方法。

错误的做法2:

将fly()和quack()方法从Duck中取出放入Flyable()和Quackable()接口中,然后让会飞和会叫的鸭子去实现这两个接口。这样虽然解决了第一个问题,让鸭子们只拥有自己该有的方法。但是代码却没有得到复用,一旦需要修改某个行为,就必须往下追踪,并去每一个具备该行为的类中修改,当子类的数目特别多的时候,效率会特别低下。

正确的做法:

创建行为接口FlyBehavior,里面放一个抽象的fly()方法,然后创建两个飞行行为的类FlyWithWings和FlyNoWay实现FlyBehavior接口并将fly()方法具体实现。同理创建QuackBehavior接口和两个叫声行为的类Qucak和MuteQuack去实现QuackBehavior接口,实现不同的quack()方法。

这样鸭子的飞行和叫声行为就委托给了FlyBehavior和QuackBehavior。将FlyBehavior和QuackBehavior当做成员放在Duck类中(即采用 “组合” ),鸭子类中不再有Fly()和Quack()方法,而是performFly()和performQuack()方法,通过成员FlyBehavior和QuackBehavior调用Fly()和Quack()方法

这样的话,如果某个行为的实现细节需要改变,直接去FlyBehavior和QuackBehavior的少数子类中修改就行了,而不用像之前那样挨个去修改几十种鸭子的行为。

以下是Duck的代码

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    public abstract void display();

    public void performQuack(){
        quackBehavior.quack();
    }

    public void performFly(){
        flyBehavior.fly();
    }
    
//可以通过如duck.setFlyBehavior(new FlyWithWings())来设定飞行行为
    public void setFlyBehavior(FlyBehavior fb){  
        flyBehavior = fb;
    }

    public void  setQuackBehavior(QuackBehavior qb){
        quackBehavior = qb;
    }
}

以下是其中一种红头鸭子的代码

public class MallardDuck extends Duck {

    MallardDuck(){
        flyBehavior = new FlyWithWings();//类变量flyBhehavior继承自Duck
        quackBehavior = new Quack();//类变量quackBehavior继承自Duck
        
    }

    public void display(){
        System.out.println("I am a MallardDuck");
    }
}

总结

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

两个设计原则:

1、针对接口编程,而不是针对实现编程
2、多用组合,少用继承

组合

利用 “has a” 关系,在本例中,每个鸭子都有一个FlyBehavior和一个QuackBehavior,将飞行行为和叫声行为委托给它们俩完成。

当你将两个类结合起来使用,这就是 组合 ,这与继承不同的地方在于,鸭子的行为不是继承而来的,而是和适当的行为对象组合而来。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值