java 设计模式 学习笔记(5) 装饰模式

装饰模式:   动态地给一个对象添加额外的职责。就增加功能来说,装饰模式比增加子类更加灵活。

 

我承认我看了《大话设计模式》 中的装饰模式,花了一个小时才消化掉,为此,我改写了《大话设计模式》 的例子以便加深印象。

在这里,我简单的以给某个人类穿衣服裤子等行为来表示对一个对象的装饰动作。

1. 根据面向接口编程的原则,建立一个 Humen 类,这个类是一个抽象类,并有一个抽象方法 dress()   ,是人类都要穿衣服吧。

 

 

2. 建立 Baby  类作为 Humen 的子类,并重写 dress 方法。不过Baby 怎么重写dress 方法 ?当然是哭闹说:“我要起床,要穿衣服”。实际上他是不会给自己穿衣服的。

3. Baby 要起床,但是不会自己穿衣服,这个时候就需要其他人来为 Baby 穿衣服。但是 Baby  今天说我要先穿外套,然后再穿裤子,明天说我要先穿裤子,然后穿外套。或者说今天我就只穿裤子,不穿外套了。对于Baby 的要求,无人能够拒绝。

  对于Baby 的不同穿衣要求,我们可以先建立一个的 Decorator 类,用来负责为 Baby 穿衣服。

Decorator  作为抽象装饰类,表示这个类还需要被继承,并希望其子类能够扩展Humen 的功能。因为 Decorator 是抽象类,其必须被继承。同时 Decorator  需要保存一个 Humen 引用,这个Humen 就是装饰类需要去装饰的对象。

 

 

 

 

4. 既然有抽象类,那么就建立一个JacketDecorator 类作为 Decorator 子类,JacketDecorator 同时也是 Humen 的孙子类,因此也必须重写 dress ()  方法,它的 dress()方法 就是听到 Baby 说要起床后就给 Baby 穿 Jacket 。

 

 

 

5. 有了穿 外套的类,那还需要一个 为Baby 穿裤子的类,功能和JacketDecorator  类似

 

 

 

 

6.提一个先给Baby 穿 外套,再穿裤子的需求   编写一个测试的类,来验证试验的正确性 :

 

 

  结果是 :

  

 

 

 

讨论:

     在最后的测试类中,有一个令人容易迷惑的地方:

   jDecorator.setHumen(baby);
  tDecorator.setHumen(jDecorator);
  tDecorator.dress();

 

   为什么能够做到先穿外套,再穿裤子?

    首先  jDecorator 中保存了一个 Baby 的对象引用 baby

         tDecorator.setHumen(jDecorator); 表示  tDecorator 又保存了一个 JacketDecorator 对象的引用 tDecorator

         这三个对象的关系是     jDecorator 保存了 baby ,tDecorator 保存了 jDecorator 。

 

         TrouserDecorator 类中的 dress()   方法:

               

      从代码可以得知,首先要 执行 父类的  dress()  方法,然后才能执行 TrouserDecorator  的装饰方法,也就是 addTrousers() 方法。回溯到  TrouserDecorator   的父类 Decorator 的 dress()方法:

       

       humen 对象就是 通过  setHumen 方法注入进来的  humen。 而在测试类里,Decorator 中的humen 就是 baby ,baby 先执行了 dress() 方法,说“ i wil get up”

      

       然后再执行 JacketDecorator 类自己的 addJacket()方法,给 baby 穿 外套

       JacketDecorator 的dress() 方法执行完了,才能轮到  TrouserDecorator   类执行自己的addTrousers() 方法,给baby 穿裤子。

 

 

 

再论:

      如果想换个需求 : 先给Baby 穿内裤,不小心把baby 惊醒了,然后给baby 穿裤子,再穿外套。

 

     这个时候,我们就需要增加一个 给 Humen 穿内裤的装饰类: BriefsDecorator 
    BriefsDecorator  类继承了 Decorator ,并重写dress()  方法,重写内容是先执行自己的 addBriefs() 方法,然后执行父类的dress()方法。

   通过这样的顺序就能保证先执行自己的 addBriefs()  方法,也就满足给baby 穿内裤,不小心 让Baby 惊醒的需求。

 

    

 

这个时候,需要改写测试类,改写后的类如下:

 

   

 

 

     解释 :  因为穿内裤动作在前,所以  bDecorator.setHumen(baby);  这样就保证了先执行 穿内裤,再执行baby 惊醒

          tDecorator.setHumen(bDecorator);  将bDecorator  注入到 tDecorator ,保证了 接着执行  addTrousers() 方法

         jDecorator.setHumen(tDecorator);   将 tDecorator  注入到jDecorator  ,保证了 最后执行 addJacket() 方法。

 

 

     

    

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值