装饰器模式是比较常用的一种设计模式,Python中就内置了对于装饰器的支持。

具体来说,装饰器模式是用来给对象增加某些特性或者对被装饰对象进行某些修改。

如上图所示,需要被装饰的对象在最上方,它自身可以有自己的实例,一般通过抽象类来实现(Java中也可以通过接口实现)。

右侧中间是一个装饰器类或者接口,其实内容与原对象基本一致,不过我们自定义的装饰器一般会继承这个装饰器基类。

最下层就是具体的装饰器了,可以看到,具体装饰器类中需要包含被装饰对象成员(也就是说,装饰器需要和被装饰对象有同样的子类),然后增加一些额外的操作。

下面的代码是一个买煎饼的例子,如我们生活中所见,可以选基础煎饼(鸡蛋煎饼,肉煎饼等),然后再额外加别的东西:

 #include<iostream>
#include<string>
using namespace std; class Pancake//基类
{
public:
string description = "Basic Pancake";
virtual string getDescription(){ return description; }
virtual double cost() = ;
}; class CondimentDecorator :public Pancake//装饰器基类
{
public:
string getDescrition();
}; class MeatPancake :public Pancake//肉煎饼
{
public:
MeatPancake(){ description = "MeatPancake"; }
double cost(){ return ; }
};
class EggPancake :public Pancake//鸡蛋煎饼
{
public:
EggPancake(){ description = "EggPancake"; }
double cost(){ return ; }
}; class Egg :public CondimentDecorator//额外加鸡蛋
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Egg"; }
Egg(Pancake* d){ base = d; }
double cost(){ return base->cost() + 1.5; }
};
class Potato :public CondimentDecorator//额外加土豆
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Potato"; }
Potato(Pancake* d){ base = d; }
double cost(){ return base->cost() + ; }
};
class Bacon :public CondimentDecorator//额外加培根
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Bacon"; }
Bacon(Pancake* d){ base = d; }
double cost(){ return base->cost() + ; }
}; int main()
{
Pancake* pan = new EggPancake();
pan = &Potato(pan);
pan = &Bacon(pan);
cout << pan->getDescription() << " $ : " << pan->cost() << endl;
system("pause");
return ;
}

可以看到,Pancake是煎饼的基类,这个基类因为定义了纯虚函数cost,所以不能被实例化。同样,装饰器基类CondimentDecorator也不能被实例化。

后面,EggPancake和MeatPancake是Pancake的派生类,是实际存在的类。

Egg、Bacon和Potato就是我们定义的装饰器对象,其中包含了Pancake的指针,可以对Pancake及其派生类进行操作。

运行代码的结果如下:

即我们选择了一个鸡蛋煎饼,然后额外加了土豆和培根,一共5+1+2=8块。

装饰器模式的优点:

1、可以轻松对已存在的对象进行修改和包装,在被装饰者的前面或者后面添加自己的行为,而无需修改原对象。

2、可以动态、不限量地进行装饰,可以更灵活地扩展功能。

相对地,装饰器模式有很明显的缺点:

1、会加入大量的小类,即使只添加一个功能,也要额外创建一个类,使得程序更复杂。

2、增加代码复杂度,使用装饰器模式不但需要实例化组件,还要把组件包装到装饰者中。

装饰器模式(Decorator) C++的更多相关文章

  1. 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)

    <?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...

  2. 设计模式(八)装饰器模式Decorator(结构型)

    设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...

  3. 装饰器模式-Decorator(Java实现)

    装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...

  4. 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现

    返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...

  5. 装饰器模式(Decorator)

    转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...

  6. 设计模式入门之装饰器模式Decorator

    //装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...

  7. 装饰器模式(Decorator)——深入理解与实战应用

    本文为原创博文,转载请注明出处,侵权必究! 1.初识装饰器模式 装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能.其结构图如下: Component为统一接口,也是装饰类和被装 ...

  8. 装饰器模式 Decorator 结构型 设计模式 (十)

    引子           现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼,  加个培根,  加个鸡蛋,多少钱?" 这句话会不 ...

  9. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  10. 23种设计模式之装饰器模式(Decorator Pattern)

    装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...

随机推荐

  1. 出现异常时直接把e输出比输出e.getMessage()好得多

    之前研究态度不好,出异常时处理草草了事,今天出现问题才觉得该认真对待每个分支.

  2. 1.shell编程之变量的高级用法

    1.1.变量替换 变量替换的六种形式 实例:非贪婪和贪婪的区别 从头部删除 [root@VM_0_9_centos shell_learn]# var_1="i love you,do yo ...

  3. Material-Animations

    https://github.com/eltld/Material-Animations

  4. win10安装Anaconda+TensorFlow+配置PyCharm

    其实很简单,我这里也只是记录一下而已. 第一大坑:anaconda必须安装4.2以前的版本,不能安装4.3以后的 版本:满满的血泪史 因为我们需要安装自带的python必须是3.5,才可以调用Tens ...

  5. Arcgis Engine(ae)接口详解(3):featureClass的feature编辑和删除

    //由于测试数据不完善,featureClass在此要只设null值,真实功能要设实际的值 IFeatureClass featureClass = null; //获取某个字段的索引,后面取字段值用 ...

  6. SQL常见问题及解决备忘

    1.mysql中:you cant't specify tartget table for update in from clause 错误 含义:在同一语句中update或delete某张表的时候, ...

  7. springboot实现定时任务的两种方式

    方式一:在springboot启动类上添加@EnableScheduling注解,然后创建具体的任务类,在方法上添加@Scheduled注解,并指明执行频率即可.如下: @Componentpubli ...

  8. 20170301 Excel 导出函数XXL_SIMPLE_API

    * XMPLT_V-COL_NO = . * XMPLT_V-COL_NAME = '物料号码'. * APPEND XMPLT_V. * * XMPLT_V-COL_NO = . * XMPLT_V ...

  9. EventStore文件存储设计

    背景 ENode是一个CQRS+Event Sourcing架构的开发框架,Event Sourcing需要持久化事件,事件可以持久化在DB,但是DB由于面向的是CRUD场景,是针对数据会不断修改或删 ...

  10. sublime text2 相关插件及其应用

    一.常见的插件 1.Emmet 'ctrl+up':切换文件: "ctrl+alt+enter":创建新的div标签: "shift+ctrl+." :查找相同 ...