2019独角兽企业重金招聘Python工程师标准>>>

装饰器模式

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

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

介绍

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

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

何时使用:在不想增加很多子类的情况下扩展类。

如何解决:将具体功能职责划分,同时继承装饰者模式。

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

应用实例: 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承。

实现

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。

RedShapeDecorator 是实现了 ShapeDecorator 的实体类。

DecoratorPatternDemo,我们的演示类使用 RedShapeDecorator 来装饰 Shape 对象。

步骤 1

创建一个接口。

class Shape{
public:virtual ~Shape(){};virtual void draw() = 0;
};

步骤 2

创建实现接口的实体类。


class Circle : public  Shape{
public:void draw() override {std::cout << "draw a circle" << std::endl;}
};class Rectangle : public  Shape{
public:void draw() override {std::cout << "draw a rectangle" << std::endl;}
};

步骤 3

创建实现了 Shape 接口的抽象装饰类。

class ShapDecorator: public Shape{
public:explicit ShapDecorator(Shape * shape):_shape(shape){}virtual void draw() override {_shape->draw();}protected:Shape * _shape;
};

步骤 4

创建扩展了 ShapeDecorator 类的实体装饰类。

class RedShapeDecorator:public ShapDecorator{
public:explicit RedShapeDecorator(Shape *shape) : ShapDecorator(shape) {}void draw() override {std::cout << "<red>" << std::endl;_shape->draw();std::cout << "<red/>" << std::endl;}
};class GreenShapeDecorator:public ShapDecorator{
public:explicit GreenShapeDecorator(Shape *shape) : ShapDecorator(shape) {}void draw() override {std::cout << "<green>"<< std::endl;_shape->draw();std::cout << "<green/>" << std::endl;}
};

步骤 5

使用 RedShapeDecorator 和 GreenShapeDecorator来装饰 Shape 对象。

    Shape * circle = new Circle();Shape * rectangle = new Rectangle();circle->draw();rectangle->draw();Shape * redDecorator = new RedShapeDecorator(circle);redDecorator->draw();Shape * greenDecorator = new GreenShapeDecorator(circle);greenDecorator->draw();delete(greenDecorator);delete(redDecorator);delete(rectangle);delete(circle);

步骤 6

验证输出。

draw a circle
draw a rectangle
<red>
draw a circle
<red/>
<green>
draw a circle
<green/>

转载于:https://my.oschina.net/fileoptions/blog/1823469

设计模式C++实现--Decorator模式相关推荐

  1. 设计模式--装饰者(Decorator)模式

    模式定义 动态(组合)地给一个对象增加一些额外的职责,就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码并且减少子类个数) 类图 应用场景 扩展一个类的功能或给一个类添加附 ...

  2. android 装饰着模式,Android与设计模式——装饰者(Decorator)模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  3. 【笔记整理】图解设计模式 | 第12章 Decorator模式(装饰边框与被装饰物的一致性)

    [笔记整理]图解设计模式 | 导航 定义 不断地为对象添加装饰的设计模式被称为Decorator模式,其中Decorator指的是"装饰物". Decorator模式中的登场角色 ...

  4. 设计模式-Decorator模式(装饰者模式)

    文章目录 装饰者模式 代码实现 为什么使用装饰者模式 装饰者模式 假如现在有一块蛋糕, 加上奶油就是奶油蛋糕.如果继续再加上草莓,就是草莓蛋糕,再加点蜡烛,就变成了生日蛋糕.不论是蛋糕.奶油蛋糕.草莓 ...

  5. 设计模式:装饰(Decorator)模式

    设计模式之装饰(Decorator)模式 在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修.相片加相框等.在软件开发过程中,有时想用一些现存的组件.这些组件可能只是完成了一些核心功 ...

  6. 设计模式-Decorator模式

    目录 一个例子(贪玩蓝月) 传统继承实现 装饰器模式实现 对比 总结 Decorator(装饰器)模式属于结构型模式. 比如当其需要三种不同的附加特性,可以为其创建三个派生类.但是若它还需要同时具有其 ...

  7. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  8. C#设计模式(9)——装饰者模式(Decorator Pattern)

    一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...

  9. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

最新文章

  1. VS2017-VC++中慎用sizeof
  2. bike with a famous logo
  3. 二维分类教案_大班数学二维分类教案
  4. springboot——kaptcha
  5. [arm驱动]linux内核时钟
  6. web前端细解cookie那些事
  7. LwIP Application Developers Manual9---LwIP and multithreading
  8. unix 系统已经消亡了吗_世界上一半的语言正在消亡。 我们应该保存它们吗?
  9. 正常的vite创建项目并且安装vue router,vant的代码示例
  10. C#之网络字节序与主机字节序互转
  11. SQL Server查询sql去掉小数位后末尾的0
  12. linux awk '{print $2}' 用法
  13. 阿里云何勉:如何定义团队的研发效能?
  14. 【数学建模】基于matlab GUI排队系统仿真【含Matlab源码 1253期】
  15. 第三章 python流程控制
  16. 16进制与字符串相互转换(C语言)
  17. uni-app使用阿里矢量图库导入 icon 彩色和黑白色
  18. 【典型液压系统】组合机床动力滑台液压系统
  19. XFCE下Screen Tearing问题的解决
  20. 微信小程序获取用户手机号存数据库,前后端都有《Java后台版 》

热门文章

  1. logback日志pattern_logback-自定义Pattern模板
  2. mac mongodb可视化工具_github项目推荐|2019 冠状病毒疫情爬虫。疫情数据可视化
  3. java复制重命名,JAVA操作文件的复制和重命名失败的原因
  4. 小马虎想用计算机计算396乘19,2020版苏教版数学四年级下册第四单元《用计算器计算》单元测试卷C卷...
  5. 安卓案例:列表控件上拉加载更多
  6. 《天天数学》连载16:一月十六日
  7. 工作任务(2012-01-03)
  8. jenkins 手动执行_Jenkins环境配置篇-增加节点
  9. 大数据平台搭建_一文读懂数据平台、大数据平台、数据中台
  10. 2017.8.10 奖励关 思考记录