设计模式5

Decorator模式
我觉得这个模式有点绕。需要很仔细的来分清其中的继承关系。
Decorator模式的使用场景:当你要描述一个东西,比如说“人”这个东西,你回构建一个人的class,它包括很多人的属性,比如身高,体重,性别,年龄等等,你还有很多的施加于“人”上面的方法,比如吃饭,睡觉,跑步等等。但是,你可能希望给“人”添加一些额外的东西,就像游戏中的人物一样,他是带装备,比如“黄金盔甲”,“蓝宝石戒指
”,“青龙大刀”。并且,游戏中人物,你光出生的时候是啥装备都没有,随着你不断练级,你的装备才越来越多,你还可以丢掉一些落后的装备,这些装备都是在游戏中动态变化的,即它是在“运行时变化的”。你静下来想想,如何设计“人”这个class,如果使用继承,你显然是无法完成的(继承意味着你必须穷尽出所有可能的“人”的子类情况),这时候你必须使用组合。如何使用组合呢?这就是Decorator模式了。

设计的时候,有3个类,第一个为Component类,它是另外2个类的父类。从Component继承来ConcreteComponent类,这个类为具体类。从Component再继承来Decorator类,其中这个类拥有一个成员变量,为Component类对象的一个引用。

对于“人”的设计,Component就是抽象的People。ConcreteComponent就是具体的“人”,他包含有人的属性(身高,体重,性别。。)。对于Decorator,从它再继承出来具体的一些装备(“黄金盔甲”为一个ConcreteDecoratorA,“蓝宝石戒指”为ConcreteDecoratorB,而“青龙大刀”为 ConcreteDecoratorC,如果出现了一个新的装备,从Decorator再继承出来一个具体的装备类就行了)。在实际使用过程中,如果你只是使用一个“裸人”那么从ConcreteComponent就可以定义出来一个对象。之后你想给他添加“黄金盔甲”,这时候你就需要使用ConcreteDecoratorA定义出一个黄金盔甲的装备,那么人的属性是如何体现呢?我们知道Decorator拥有一个Component类对象的一个引用的成员变量,只要这个成员变量引用一个“人”,就是说在Decorator的构造函数就要去传入一个“Component”对象的引用。情况如下:

ConcreteComponent*  pCom = new ConcreteComponent;
ConcreteDecoratorA* pDecA = new ConcreteDecoratorA(pCom);

从中可以看出,ConcreteDecoratorA本身就是描述了一个“人”(所以要从Component来继承),还是一个带有某种装备的“人”,人的属性表现在其包含了一个“人”对象的引用。再往下看:

ConcreteDecoratorB* pDecB = new ConcreteDecoratorB(pDecA);

由于pDecA本身就描述的是一个“人”,“黄金盔甲的人”也可以当成参数传入“蓝宝石戒指”,(这也说明Decorator要从Component继承过来),于是这个“蓝宝石戒指的人”,其人的属性表现在包含了一个“黄金盔甲的人”的引用(同时这个“黄金盔甲的人”它的人的属性是因为其包含一个“人”),如果看图的话,一个“带着蓝宝石戒指和黄金盔甲的人”的结构就是:
    --------------------------
   |    戒指                      |
   |    ------------------       |
   |   |      盔甲          |      |
   |   |     -----------    |      |
   |   |   |  具体人   |   |      |
   |   |     ------- ---     |     |
   |    -----------------  |     |
    ---------------------------    


在这里需要强调的是,ConcreteDecorator的对象就需要当成是一个component的对象,用上面的例子来说,虽然我们把装备称为“黄金盔甲”,但要晓得,程序中出现所有“黄金盔甲”的对象,都是表示““穿黄金盔甲的人””,而人的属性就是通过包含一个“xxx的人”的引用来传递。这就是为啥Decorator的父类就是component的原因。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值