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

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

意图

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

解决问题

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

如何解决

将具体功能职责划分,同时继承装饰器模式

优点

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

缺点

多层装饰比较复杂

注意事项

可代替继承

C++实现

有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。

下面给出装饰器模式UML图:

在这种设计中,手机的装饰功能被独立出来,可以单独发展,进而简化了具体手机类的设计。

Code:

//装饰器模式class Phone
{
public :Phone(){}virtual ~Phone(){}virtual void showDecorate(){}
};
class iPhone  : public Phone  //具体手机类
{
private:string name;
public:iPhone(string _name):name(_name){}~iPhone(){}void showDecorate(){cout << name<<"的装饰"<< endl;}
};
class NokiaPhone : public  Phone
{
private:string name;
public :NokiaPhone(string _name):name(_name){}~NokiaPhone(){}void  showDecorate(){cout << name <<"的装饰"<< endl;}
};class DecoratorPhone :public Phone
{
private :Phone* m_phone; //要装饰的手机
public:DecoratorPhone(Phone *phone):m_phone(phone){}virtual void showDecorate(){m_phone->showDecorate();}
};class DecoratePhoneA : public DecoratorPhone //具体的装饰A
{
public :DecoratePhoneA(Phone* ph):DecoratorPhone(ph){}void showDecorate(){DecoratorPhone::showDecorate();AddDecorate();}
private:void AddDecorate(){cout <<"增加挂件" << endl;}
};
class DecoratePhoneB : public DecoratorPhone
{
public:DecoratePhoneB(Phone* ph):DecoratorPhone(ph){}void showDecorate(){DecoratorPhone::showDecorate();AddDecorate();}
private:void  AddDecorate(){cout << "屏幕贴膜"<< endl;}
};

客户端:

int test_Decorate()  //装饰器模式
{Phone* ph = new NokiaPhone("16300");Phone *dpa = new DecoratePhoneA(ph);//增加挂件Phone* dpb = new DecoratePhoneB(ph);//增加贴膜ph->showDecorate();delete ph;delete dpa;delete dpb;system("pause");return 0;
}

装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。[DP]
       在本文的例子中,我们定义了两个具体的手机类,iPhone类和NokiaPhone类,通过单独的装饰类为它们添加特性,从而组合出复杂的功能。

与桥接模式的区别:

之前总结了C++设计模式——桥接模式;你会发现,二者都是为了防止过度的继承,从而造成子类泛滥的情况。那么二者之间的主要区别是什么呢?桥接模式的定义是将抽象化与实现化分离(用组合的方式而不是继承的方式),使得两者可以独立变化。可以减少派生类的增长。如果光从这一点来看的话,和装饰者差不多,但两者还是有一些比较重要的区别:

1.桥接模式中所说的分离,其实是指将结构与实现分离(当结构和实现有可能发生变化时)或属性与基于属性的行为进行分离;而装饰者只是对基于属性的行为进行封闭成独立的类,从而达到对其进行装饰,也就是扩展。比如:异常类和异常处理类之间就可以使用桥接模式来实现完成,而不能使用装饰模式来进行设计;如果对于异常的处理需要进行扩展时,我们又可以对异常处理类添加Decorator,从而添加处理的装饰,达到异常处理的扩展,这就是一个桥接模式与装饰模式的搭配;

2.桥接中的行为是横向的行为,行为彼此之间无关联,注意这里的行为之间是没有关联的,就比如异常和异常处理之间是没有行为关联的一样;而装饰者模式中的行为具有可叠加性,其表现出来的结果是一个整体,一个各个行为组合后的一个结果。

总结

装饰模式重点在装饰,对核心功能的装饰作用;将继承中对子类的扩展转化为功能类的组合,从而将需要对子类的扩展转嫁给用户去进行调用组合,用户如何组合由用户去决定。我在学习装饰模式时,就是重点分析了“装饰”这个词,我们都知道,装饰是在一个核心功能上添加一些附属功能,从而让核心功能发挥更大的作用,但是最终它的核心功能是不能丢失的。这就好比我们进行windows shell开发时,我们是对windows的这层壳进行了功能的装饰,从而实现了我们需要的一些装饰功能,但是最终的功能还是由windows shell去完成。这就好比,我们的装饰就是给核心功能添加了一层外衣,让它看起来更漂亮和完美。

参考:
http://www.jb51.net/article/55882.htm

http://blog.csdn.net/wuzhekai1985/article/details/6672614

设计模式---装饰器模式(C++实现)相关推荐

  1. Python设计模式-装饰器模式

    Python设计模式-装饰器模式 代码基于3.5.2,代码如下; #coding:utf-8 #装饰器模式class Beverage():name = ""price = 0.0 ...

  2. Go 设计模式 - 装饰器模式

    装饰模式使用对象组合的方式动态改变或增加对象行为.Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式.使用匿名组合,在装饰器中不必显式定义转调原对象方法. 设计模式 装饰器模式 装饰器模式主要 ...

  3. Spring设计模式(装饰器模式)

    Spring设计模式(装饰器模式) 模式的定义: 装饰者模式定义: ​ 动态地为一个对象添加一些额外的职责,若要扩展一个对象的功能,装饰者提供了比继承更有弹性的替代方案. 模式的结构图 : 模式包含角 ...

  4. Java设计模式-装饰器模式 理论代码相结合

    继Java设计模式适配器模式后的装饰器模式来啦,让我们一起看看吧. 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一 ...

  5. 设计模式--装饰器模式

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

  6. PHP设计模式——装饰器模式

    声明:本系列博客参考资料<大话设计模式>,作者程杰. 装饰器模式又叫装饰者模式.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装 ...

  7. 设计模式-装饰器模式 C++

    一.简介 1.什么是装饰器模式 装饰器模式是结构型设计模式. 装饰器是现有类的一个包装,可以在不修改现有类且不增加子类的情况下扩展现有类. [注]可以实现向一个现有对象添加新的功能,同时又不改变其结构 ...

  8. C++设计模式 装饰器模式

    文章目录 1. 先验知识 2. 装饰器模式相关概念 3. 装饰器模式的应用 3.1 应用1: 给形状添加新的特征 不同形状加红 3.2 应用2: 给一个人穿不同的衣服 a 直接person类, 增加穿 ...

  9. 白话设计模式-装饰器模式的使用和意义

    装饰器模式展示 在学习设计模式的过程中,将自己对于设计模式的理解,以最简单,最白话的方式,分享给大家.个人觉得,对于设计模式的理解,需要将他从最抽象的理论里,真实的代入到实际的业务场景中,将会有最深刻 ...

最新文章

  1. 微信跳一跳高分辅助踩坑
  2. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
  3. vue 百度统计_百度暑期实习前端开发面经
  4. 【深度学习】270篇CVPR 2020代码开源的论文,全在这里了!
  5. 浏览器内核与web标准
  6. Visio使用技巧总结
  7. Java Jna调用Dll动态库函数读写IC卡
  8. chrome 您的浏览器禁用了Javascript
  9. 小米刷入Recovery
  10. 产品经理需要掌握的十大知识模块
  11. 图灵 数理逻辑 人工智能 图灵机与计算问题 论文
  12. python学习笔记_week14
  13. RB-tree性质理解
  14. JavaScript从初级往高级走系列————prototype
  15. 纵观虚拟现实在各行各业的应用,虚拟现实技术目前依然处在零星的散状的实验阶段。
  16. 解决不同部门间防火墙的需求问题(转)
  17. 微软账户无法登录 提示0x800704cf
  18. 铁打的营盘,流水的兵
  19. 【MySQL系列】Java的JDBC编程
  20. flask下载excel文件

热门文章

  1. ios快捷指令:修改图片尺寸、拼接长图
  2. JAVA 通过属性名称 获取属性值、设置属性值
  3. java poi操作word模版 导出word文档(附工具类)
  4. excel 一键给公司所有员工发送工资单 vba代码
  5. 【干货】信息系统项目监理浅视简识,附高清下载
  6. Qt 3D:线框 QML 示例
  7. 郭静:新交规火了蓝牙耳机
  8. 链表及经典问题(船长系列)
  9. Tensorboard无法显示图片
  10. 服务器系统不用关机,云服务器不用了要关机吗