• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++设计模式之装饰模式

C++设计模式之装饰模式

作者:果冻想 字体:[增加 减小] 来源:互联网 时间:2017-05-28

果冻想 通过本文主要向大家介绍了c++设计模式,c++设计模式pdf,c++设计模式视频教程,c++设计模式视频,c++设计模式面试题等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

前言

在实际开发时,你有没有碰到过这种问题;开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作;而有一些非核心的操作,可能会使用,也可能不会使用;现在该怎么办呢?

1.将这些非核心的操作全部放到类中,这样,一个类就包含了很多核心的操作和一些看似有关,但是又无关的操作;这就会使核心类发生“爆炸”的现象,从而使核心类失去了一定的价值,也使使用核心类的客户在核心操作和非核心操作中挣扎;

2.使用继承来扩展核心类,需要使用核心类时,直接建立核心类对象;当需要使用核心类扩展类时,就建立核心类扩展类对象;这样貌似是一种很有效的方法;但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;同时,又掉入了另一个陷阱,随着扩展功能的增多,子类也会增多,各种子类的组合,就会导致类的膨胀,最后,就会被淹没在类的海洋;此时,也不用我多说,你是不是想起了桥接模式,桥接模式就是为了适应多个维度的变化而发生子类“爆炸”的情况,但是,桥接模式是为了适应抽象和实现的不同变化,并不适用于我这里说的。那如何是好,这就要说到今天总结的装饰模式了。

什么是装饰模式?

在GOF的《设计模式:可复用面向对象软件的基础》一书中对装饰模式是这样说的:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面向对象的设计中,而我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。装饰器模式的本质就是动态组合。动态是手段,组合才是目的。总之,装饰模式是通过把复杂的功能简单化,分散化,然后再运行期间,根据需要来动态组合的这样一个模式。它使得我们可以给某个对象而不是整个类添加一些功能。

UML类图

Component:定义一个对象接口,可以给这些对象动态地添加职责;

ConcreteComponent:定义一个具体的Component,继承自ConcreateComponent,重写了Component类的虚函数;

Decorator:维持一个指向Component对象的指针,该指针指向需要被装饰的对象;并定义一个与Component接口一致的接口;

ConcreteDecorator:向组件添加职责。

代码实现:

/*
** FileName     : DecoratorPatternDemo
** Author       : Jelly Young
** Date         : 2013/12/19
** Description  : More information, please go to http://www.weikejianghu.com
*/
#include <iostream>
using namespace std;
class Component
{
public:
     virtual void Operation() = 0;
};
class ConcreteComponent : public Component
{
public:
     void Operation()
     {
          cout<<"I am no decoratored ConcreteComponent"<<endl;
     }
};
class Decorator : public Component
{
public:
     Decorator(Component *pComponent) : m_pComponentObj(pComponent) {}
     void Operation()
     {
          if (m_pComponentObj != NULL)
          {
               m_pComponentObj->Operation();
          }
     }
protected:
     Component *m_pComponentObj;
};
class ConcreteDecoratorA : public Decorator
{
public:
     ConcreteDecoratorA(Component *pDecorator) : Decorator(pDecorator){}
     void Operation()
     {
          AddedBehavior();
          Decorator::Operation();
     }
     void  AddedBehavior()
     {
          cout<<"This is added behavior A."<<endl;
     }
};
class ConcreteDecoratorB : public Decorator
{
public:
     ConcreteDecoratorB(Component *pDecorator) : Decorator(pDecorator){}
     void Operation()
     {
          AddedBehavior();
          Decorator::Operation();
     }
     void  AddedBehavior()
     {
          cout<<"This is added behavior B."<<endl;
     }
};
int main()
{
     Component *pComponentObj = new ConcreteComponent();
     Decorator *pDecoratorAOjb = new ConcreteDecoratorA(pComponentObj);
     pDecoratorAOjb->Operation();
     cout<<"============================================="<<endl;
     Decorator *pDecoratorBOjb = new ConcreteDecoratorB(pComponentObj);
     pDecoratorBOjb->Operation();
     cout<<"============================================="<<endl;
     Decorator *pDecoratorBAOjb = new ConcreteDecoratorB(pDecoratorAOjb);
     pDecoratorBAOjb->Operation();
     cout<<"============================================="<<endl;
     delete pDecoratorBAOjb;
     pDecoratorBAOjb = NULL;
     delete pDecoratorBOjb;
     pDecoratorBOjb = NULL;
     delete pDecoratorAOjb;
     pDecoratorAOjb = NULL;
     delete pComponentObj;
     pComponentObj = NULL;
}
</div>

使用场合

1.在不影响其他对象的情况下,以动态的,透明的方式给单个对象添加职责;
2.处理那些可以撤销的职责;
3.当不能采用生成子类的方法进行扩充时。一种情况是,可能存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

注意事项

1.接口的一致性;装饰对象的接口必须与它所装饰的Component的接口是一致的,因此,所有的ConcreteDecorator类必须有一个公共的父类;这样对于用户来说,就是统一的接口;

2.省略抽象的Decorator类;当仅需要添加一个职责时,没有必要定义抽象Decorator类。因为我们常常要处理,现存的类层次结构而不是设计一个新系统,这时可以把Decorator向Component转发请求的职责合并到ConcreteDecorator中;

3.保持Component类的简单性;为了保证接口的一致性,组件和装饰必须要有一个公共的Component类,所以保持这个Component类的简单性是非常重要的,所以,这个Component类应该集中于定义接口而不是存储数据。对数据表示的定义应延迟到子类中,否则Component类会变得过于复杂和臃肿,因而难以大量使用。赋予Component类太多的功能,也使得具体的子类有一些它们它们不需要的功能大大增大;

实现要点

1

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解C++之策略模式
  • C++设计模式之工厂模式
  • C++设计模式编程中简单工厂与工厂方法模式的实例对比
  • 详解C++设计模式编程中对访问者模式的运用
  • 深入解析C++设计模式编程中解释器模式的运用
  • C++设计模式编程之Flyweight享元模式结构详解
  • 详解C++设计模式编程中责任链模式的应用
  • C++设计模式编程中使用Bridge桥接模式的完全攻略
  • C++设计模式编程中的迭代器模式应用解析
  • 深入剖析设计模式中的组合模式应用及在C++中的实现

相关文章

  • 2017-05-28C语言 运算符详细介绍及示例代码
  • 2017-05-28排列和组合算法的实现方法_C语言经典案例
  • 2017-05-28从汇编看c++中变量类型的深入分析
  • 2017-05-28C++实现读入二进制数并转换为十进制输出
  • 2017-05-28浅析iterator与指针的区别
  • 2017-05-28C++基础入门教程(一):基础知识大杂烩
  • 2017-05-28VC中使用ADO开发数据库应用程序简明教程
  • 2017-05-28VC++中的字体设置方法详解
  • 2017-05-28C/C++产生随机数函数简单介绍
  • 2017-05-28C++基本算法思想之递推算法思想

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言 以字符串的形式读写文件详解及示例代码
    • C语言中的隐式函数声明
    • C++中的friend友元函数详细解析
    • C语言从txt文件中逐行读入数据存到数组中的实现方法
    • C语言辗转相除法求2个数的最小公约数
    • C++如何调用matlab函数
    • 基于C++实现kinect+opencv 获取深度及彩色数据
    • C语言 基本语法示例讲解
    • 概率的问题:使用递归与多次试验模拟的分析
    • 深入学习C++中的函数概念

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有