前言:
当希望动态地为一个对象(有时候我们想给某个对象添加一些职责, 而不是整个类)填写一些额外的职责时, 修饰模式比生成子类更加的灵活

示例:
以一个CTextView为例, 我们现在有一个文本视图类, 该类提供一个基本的文本编辑框, 当我们渴望拥有一个带滚动条的文本视图时, 我们也许会从CTextView类中派生出一个CScrollTextVIew, 而当我们想要一个带边框的文本视图时, 我们也许会派生出一个CBorderTextView, 可是如果我们想要一个既带滚动条, 又拥有边框的文本视图呢? CScrollBorderTextView? 也可以, 但这并不灵活

如果现在需求发生变动, 我想要有一个边框, 当文本过多时, 它有垂直滚动条, 当文本过长时, 它有水平滚动条, 当客户希望时, 它又可以有阴影等效果, 如果继续使用继承的方式来满足需求, 我想应当是非常痛苦的

修饰模式可以满足我们的需求, 它使我们可以为一个对象添加一些额外的职责, 而这些额外的职责对于对象本身而言是透明的

代码:

// 抽象视图类
class CView
{
// 函数定义
public:// 构造函数CView(void) {}// 析构函数~CView(void) {}// 外部接口
public:// 绘制函数virtual void Draw(void) {}
};// 抽象装饰类
class CDecorate:public CView
{
// 变量定义
private:CView* m_pView;// 函数定义
public:// 构造函数CDecorate(CView* view) { m_pView = view; }// 析构函数~CDecorate(void) {}// 外部接口
public:// 绘制函数virtual void Draw(void) { m_pView->Draw(); }
};// 滚动条装饰类
class CScrollBars:public CDecorate
{
// 函数定义
public:// 构造函数CScrollBars(CView* view) : CDecorate(view){}// 析构函数~CScrollBars(void) {}// 内部函数
protected:// 绘制滚动条void DrawScrollBars(void){printf("> 绘制一个滚动条\r\n");}// 外部接口
public:// 绘制函数virtual void Draw(void){CDecorate::Draw();DrawScrollBars();}
};// 边框装饰类
class CBorder:public CDecorate
{
// 函数定义
public:// 构造函数CBorder(CView* view) : CDecorate(view){}// 析构函数~CBorder(void) {}// 内部函数
protected:// 绘制边框void DrawBorder(void){printf("> 绘制一个边框\r\n");}// 外部接口
public:// 绘制函数virtual void Draw(void){CDecorate::Draw();DrawBorder();}
};// 文本视图类
class CTextView:public CView
{
// 变量定义
protected:char m_Text[MAX_PATH];// 函数定义
public:// 构造函数CTextView(char* s) { SetWindowText(s); }// 析构函数~CTextView(void) {}// 内部函数
protected:// 绘制文本视图virtual void DrawTextView(void){printf("> 绘制一个文本视图, 文本内容为:%s\r\n", m_Text);}// 外部接口
public:// 绘制函数virtual void Draw(void){CView::Draw();DrawTextView();}// 设置窗口文本void SetWindowText(char* s){strcpy_s(m_Text, _countof(m_Text), s);}// 获取窗口文本char* GetWindowText(void){return m_Text;}
};// 窗口类
class CWindows
{
// 变量定义
protected:CView* m_arrWindow[10];// 函数定义
public:// 构造函数CWindows(void) { ZeroMemory(m_arrWindow, sizeof(CView*) * 10); }// 析构函数~CWindows(void) { ZeroMemory(m_arrWindow, sizeof(CView*) * 10); }// 外部接口
public:// 绘制窗口void Draw(void){for (int nI=0; nI<10; nI++){if (m_arrWindow[nI] != NULL)    m_arrWindow[nI]->Draw();}}// 添加控件void AddControl(CView* pView){for (int nI=0; nI<10; nI++){if (m_arrWindow[nI] == NULL)    { m_arrWindow[nI] = pView; break; }}}// 移除控件void RemoveControl(CView* pView){for (int nI=0; nI<10; nI++){if (m_arrWindow[nI] == pView)   { m_arrWindow[nI] = NULL; break; }}}
};int _tmain(int argc, _TCHAR* argv[])
{// 定义一个窗口对象CWindows WindowsObject;// 定义一个普通的文本视图CTextView TextView("我是一个文本视图控件");// 将文本视图作为一个控件添加进窗口对象中WindowsObject.AddControl(&TextView);// 使窗口对象绘制自身WindowsObject.Draw();printf("----------------------------------------\r\n");// 将文本视图从窗口对象中移除WindowsObject.RemoveControl(&TextView);
//---------------------------//// 现在给这个文本视图加上一个滚动条CScrollBars* pScrollBars = new CScrollBars(&TextView);// 添加"带滚动条的文本视图"到窗口对象中WindowsObject.AddControl(pScrollBars);// 使窗口对象绘制自身WindowsObject.Draw();printf("----------------------------------------\r\n");// 将"带滚动条的文本视图"从窗口对象中移除WindowsObject.RemoveControl(pScrollBars);delete pScrollBars;
//---------------------------//// 现在给这个文本视图加上一个边框CBorder* pBorderObject = new CBorder(&TextView);// 添加"带边框的文本视图"到窗口对象中WindowsObject.AddControl(pBorderObject);// 使窗口对象绘制自身WindowsObject.Draw();printf("----------------------------------------\r\n");// 将"带边框的文本视图"从窗口对象中移除WindowsObject.RemoveControl(pBorderObject);delete pBorderObject;
//---------------------------//// 现在给这个文本视图加上一个边框, 又加上一个滚动条CBorder* pBorderScrollBars = new CBorder(new CScrollBars(&TextView));// 添加"既带边框, 又带滚动条的文本视图"到窗口对象中WindowsObject.AddControl(pBorderScrollBars);// 使窗口对象绘制自身WindowsObject.Draw();printf("----------------------------------------\r\n");// 将"既带边框, 又带滚动条的文本视图"从窗口对象中移除WindowsObject.RemoveControl(pBorderScrollBars);delete pBorderObject;
//---------------------------//getchar();return 0;
}

总结:
修饰模式的好处在于可以在运行时刻随时随地的为某个对象添加或删去一些额外的职责, 而对象本身对此并不知情

Decorate(修饰模式)相关推荐

  1. PS中的画笔工具和修饰模式(画笔模式)

    1.画笔工具的认识和作用 画笔工具组在绘画与修饰工具组下面. 画工具的作用不是用来画画的 画笔工具是PS中核心知识点的一项内容 画笔工具重在局部修饰,重在局部修图 选择很重要,蚂蚁线不重要. PS经常 ...

  2. 「大话设计模式 - 解读」1 策略、修饰、代理模式

    策略模式 在日常中,我们常随着时间的不同对同一件事的处理会发生不同.就好像一件物品,在购物平台上的销售策略会发生变化,时而打折,时而满xx元返xx元.这些都是不同的策略,然后策略是无法穷尽的,他们都有 ...

  3. 修饰器模式(day04)

    修饰器设计模式 --最近我给女朋友买了一款可以更换外壳的手机.现在的外壳是红色的,假如我想用这款手机的时候,会更换成银灰色的外壳.但是我不能随意更换天线或者话筒,因为这些功能模块在手机生产的时候就已经 ...

  4. 反模式? 只有模式不彻底吧

    我认为,没有反模式,只有模式不彻底. " 某人说:"软件都不是一个人能写出来的,我们需要去整体控制." 他快要走了,那个影响我太多的人. " 1. Cremat ...

  5. php和python对比-PHP、Python和Javascript的装饰器模式对比

    修饰模式(Decorator Pattern),又叫装饰者模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式.就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个 ...

  6. 设计模式学习----装饰器模式

    这两天本来是自在学习java collection Framework的Fail Fast底层机制,看到核心的部分时,突然意识到设计模式的问题,上大学到现在我还没有真正理解过设计模式的概念,于是用了大 ...

  7. 23种设计模式C++源码与UML实现--装饰者模式

    装饰者模式 github代码仓库 装饰者模式(Decorator)又叫包装模式,通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替代方案. 装饰模式就是把要添加的功能分别放到单独的类中,并 ...

  8. 设计模式——代理模式与装饰模式的异同

    两种模式的特点 装饰模式: 在不改变接口的前提下,动态扩展对象的访问. 动态继承,让类具有在运行期改变行为的能力. 装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为. 强调: ...

  9. Java 经典设计模式-- 03.结构型模式

    前言 书接上文,上一篇中创建型设计模式中的常用设计模式做了简单的介绍,本篇将继续对结构型设计模式中的常用模式进行介绍与分析. 目录: 适配器模式 桥接模式 组合模式 修饰模式 代理模式 简单提及: M ...

  10. 设计模式-装饰者模式(给阿姨倒杯卡布奇诺)

    文章目录 引例 一般解法 装饰者模式 装饰者解法 引例 给阿姨倒杯卡布奇诺,需要加两份牛奶.一份糖. 需求:设现在有单品咖啡:Espresso(意大利浓咖啡)和LongBlack(美式咖啡),调料有M ...

最新文章

  1. 找不到命令报错bash:command not found解决方案
  2. Ollivander's Inventory(连接查询、单表双实例、子查询)
  3. 打印 指定目录下和子目录下的的所有.java文件的路径. (使用FileFilter过滤器)
  4. 批量部署虚拟机实战解析
  5. ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台(elk5.2+filebeat2.11)
  6. android.mk 模块编译,通过Android.mk添加一个编译模块到系统中的顺序如下
  7. 工作392-选择Hbuilder x导入项目
  8. Docker配置国内加速镜像源
  9. eclipse中JPA插件的安装与使用
  10. [转]CG编程概念 ,及CG编译器与VC6.0集成方法
  11. Chelly的串串专题
  12. APISpace 通用文字识别OCR接口 免费好用
  13. 微信小程序 - 快速搭建微信小程序demo
  14. web测试的基本测试点
  15. Node.js简介及安装
  16. SVG格式化<PATH>说明
  17. 【收集】键盘钢琴 和弦琴谱 (带HTML版开发流程)
  18. MVC5 - ASP.NET Identity登录原理-Claims-based认证和OWIN
  19. 【基操】word插入的表格无法修改列宽
  20. 今天测试了两个跑步软件

热门文章

  1. 计算机excel表格公式教程,职称计算机Excel教程:显示公式的方法
  2. MySQL 基础学习笔记
  3. springboot+老年康复中心信息管理系统 毕业设计-附源码250859
  4. 深度学习论文: Avoiding Overfitting: A Survey on Regularization Methods for Convolutional Neural Networks
  5. PLSQL连接Oracle 数据库配置详解
  6. cp 命令 提示cp: 略过目录 “/root/temp/sk”
  7. 借助高德LBS开放平台打造属于国人的LBS+AR游戏
  8. Windows7桌面图标蓝底阴影怎么解决?
  9. Image Enhancement
  10. 之江汇空间如何加音乐背景_如何给空间添加背景音乐