设计模式之装饰者模式(一)

经过前两个模式的学习,是不是对设计模式有了进一步的认识了呢,现在,我们继续冲鸭。

本章可以称为“给爱用继承的人一个全新的设计眼界”。这里我们即将再度探讨典型的继承滥用问题,我们将学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦熟悉了装饰的技巧,你将能够在不修改任何底层代码的情况下,给对象赋予新的职责。

之前我们见识了鸭子的各个表现会飞、会游泳、会叫、会跳;也看过了气象台实时更新的能力,在看板里把数据更新;接下来我们一起来喝下咖啡,体验一把喝咖啡的乐趣。咖啡店里的生意太好了,需要升级现有的产品,所以店主准备更新订单系统,以此来满足店内各位顾客。

先来看一张图,这是原先的店内设计

看出什么来了吗?没错,就是各个类来满足对咖啡的不同要求。那么,如果店内产品需要升级,比如购买咖啡时,想加入各种调料,例如:蒸奶,豆浆,摩卡或者覆盖奶泡。咖啡店根据不同的调料,收取不同的费用,所以有多少种调料,就有多少种类,是这个意思没错吧。然后,就会很悲剧,请看下面扩展调料之后的图


我的天,这是啥,这要是写了这样的项目,还不是分分钟要被哭死,维护这么多的类。

认识装饰者模式

当前遇到的问题就是:类数量爆炸、设计死板、以及基类加入的新功能并不适用于所有的子类。

所以,装饰者要隆重出场。在这里要采用不一样的做法:我们要以饮料为主体,然后再运行试以调料来“装饰”(decorate)饮料。加入某个顾客想要摩卡和奶泡深培咖啡,那么具体的做法就可以是:

  1. 拿一个深培咖啡(DarkRoast)对象
  2. 以摩卡(Mocha)对象装饰它
  3. 以奶泡(Whip)对象装饰它
  4. 调用cost方法,并依赖委托(delegate)将调料的价钱加上去

以装饰者构造饮料订单

为了让读者更加清晰的了解,小编在这里直接给了书中的图来表示

根据以上信息,我们知道

  • 装饰者和被装饰对象有相同的超类型
  • 你可以用一个或多个装饰者包装一个对象
  • 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它
  • 装饰者可以在所委托被装饰者的行为之前/或之后,加上自己的行为,以达到特定的目的---关键点
  • 对象可以在任何时候被装饰,所以可以再运行时动态地、不限量地用你喜欢的装饰者来装饰对象

来看看装饰者模式的定义吧。

定义装饰者模式

装饰者模式动态地将责任附加到对象上。若要扩展功能呢,装饰者提供了比继承更有弹性的替代方案。

那么我们如何在现实中实际应用装饰者模式呢,先来看看根绝角色来分配的类图

装饰我们的饮料

从上面的类图,看出什么了吗?想到我们的饮料的类图怎么画了没呢。接下来,就让我们照猫画虎,来画一个属于我们的装饰类类图

鉴于之前有读者反映,说出现篇幅过长的情况。小编自己也曾疑惑,到底怎么更好地控制篇幅。所以,从今天开始,小编在力争保持思路一惯性的条件下,模块分的更细致,篇幅更加适中,让碎片化时间得到充分的利用。

所以,今天的学习就先到这里啦。下一篇,会针对类图进行实际的代码编写以及其他补充性的情况。大家也可以先根据代码,在伪代码的世界里实践下,也利于咱们下次的编码实战。

PS:代码已经上传,需要查看的朋友点击此处HeadFirstDesign

爱生活,爱学习,爱感悟,爱挨踢

image

posted on 2019-04-03 10:16  程序员小跃  阅读(1102)  评论(0编辑  收藏  举报

导航