【软件设计师中级】设计模式之装饰器模式学习笔记(c++)

本文详细介绍了装饰器模式的概念、结构和适用性,通过一个牛肉面馆的例子来生动阐述其工作原理。在C++代码实现部分,展示了如何使用装饰器模式动态地给对象添加职责,以及如何通过装饰器的子类来实现功能的增减。通过代码解析,解释了如何通过装饰器模式实现一系列操作的串联,强调了代码的灵活性和可扩展性。
摘要由CSDN通过智能技术生成

1、decorator(装饰)

(1)意图

动态的给以个对象添加一些额外的职责。就增加功能而言,decorator模式生成子类更加灵活。

(2)结构

装饰器模式

componet定义一个对象的接口,可以给这些对象动态的添加职责

concretecomponet定一个对象,可以给这个对象添加职责

decorator维持一个指向component对象的指针,并定一个与component接口一致的接口

concretedecorator想组组建添加职责

(3)适用性

在不影响其他对象的情况下,以动态、透明的方式给单位的对象添加职责

处理哪些可以撤销的职责。

当不能采用生成子类的方式进行扩充时候,一种情况是,可能有大量的独立扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长,另一种情况可能是由于定义被隐藏,或类定义又用于生成子类。

2、根据UML编写代码

根据对代uml图的展示,该uml主要涉及2个关系,一个是泛化关系一个是关联关联(聚合)

(1)泛化关系

该关系用在父类与子类的之间,比如component为decorator的父类,后者为前者的子类。

(2)关联关系

decorator与component之间保持关联关系,即在decorator中生成一个"component*"的指针用于对传入的component类及子类进行操作。

(3)UML框架解析

我们通过component下的concretecomponent对我们想要的效果进行一个实际的操作,然后在通过decorator的子类对concretecomponent的operation的结果进行补充或者删除。

(4)代入生活举例 

   假如整个uml图是一个牛肉面馆,concretecomponent(点餐员)对着component(后厨)客人点了一碗牛肉面(concretecomponent->operation()),同时对后厨说客人提了特殊要求(decorator)希望多加点香菜(concretedecoratorA)和少放点辣椒(concretedecoratorB)

3、代码实现

#include<iostream>
using namespace std;
class component{//服务人员
    public:
        virtual void opreation()=0;
};

class concretecomponent:public component{//服务员将客人的需求报告给后厨,并只做一碗普通的牛肉面
    public:
        void opreation(){
            cout<<"客人点了一碗牛肉面"<<endl;
        }
};

class decorator:public component{//客人的特殊需求
    public:
        virtual void opreation(){};
        component *p;//形成一个指针方便对普通的牛肉面并进行一些操作
};
class concretedecoratorA:public decorator{
    public:
        concretedecoratorA(component *p){
            decorator::p=p;//this=>p=p; 
        }
        void opreation(){
            p->opreation();//执行之前的职责
            cout<<"请多加香菜"<<endl;//增加职能
        }
};

class concretedecoratorB:public decorator{
    public:
        concretedecoratorB(component *p){
            decorator::p=p;//this=>p=p;
        }
        void opreation(){
            p->opreation();
            cout<<"少放辣椒"<<endl;//减少职能
        }
};
int main(){
    component *noodle =new concretecomponent();//客人点了一碗牛肉面
    noodle=new  concretedecoratorA(noodle);//代码核心所在,在牛肉面的基础上添加客人的特殊需求1,形成一碗新的牛肉面
    noodle=new  concretedecoratorB(noodle);//在新的牛肉面的基础上再添加客户一个特殊需求后,形成一个最终的牛肉面
    noodle->opreation();//把满足客户所有需求的牛肉面端上桌
    return 0;
}

特别注意一个地方,一碗牛肉面不可能都做好了,放在客人桌上了再给客人加香菜和少放辣椒,原则上应该一次性弄好端到客人桌子上,程序中用 noodle->opreation()这一行代码一次性实现了所有的操作。noodle->opreation()这行代码中的这个noodle到底是啥样子的?经过我们的无数次套娃,其实他是这样子:

    noodle=new  concretedecoratorB(new  concretedecoratorAnew concretecomponent()  );

我在执行opreation() 程序会从最里面的  new concretecomponent() 从内到外一层一层反向执行。

如果上诉代码实在难以理解我们换个方式:

int main(){
    component *noodle =new concretecomponent();   
    component *noodle1 =NULL;
    component *noodle2 =NULL;
    noodle1=new  concretedecoratorA(noodle);
    noodle2=new  concretedecoratorB(noodle1);
    noodle2->opreation();    
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值