1.意图

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

2.别名

包装器 Wrapper.

3.动机

给某个对象而不是整个类添加一些功能。一个较为灵活的方式时将组件嵌入另一个对象中。

4.适用性

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

5.结构

6.代码实例

#include <memory>

class Component
{
public:
virtual void Operation()=;
}; class ConcreteComponent : public Component
{
public:
void Operation();
}; class Decorator : public Component
{
public:
virtual void Operation();
void SetComponent(std::shared_ptr<Component> pComponent);
protected:
std::shared_ptr<Component> m_pComponent;
}; class ConcreteDecoratorA : public Decorator
{
public:
void Operation();
void OtherBehavior(); }; class ConcreteDecoratorB : public Decorator
{
public:
void Operation();
void OtherBehavior(); };
#include "Component.h"
#include <iostream> void ConcreteComponent::Operation()
{
std::cout << "ConcreteComponent Operation executed" <<std::endl;
} void Decorator::Operation()
{
m_pComponent->Operation();
} void Decorator::SetComponent(std::shared_ptr<Component> pComponent)
{
m_pComponent = pComponent;
} void ConcreteDecoratorA::Operation()
{
Decorator::Operation();
OtherBehavior();
} void ConcreteDecoratorA::OtherBehavior()
{
std::cout<<"ConceteDecoratorA OtherBehavior executed" << std::endl;
} void ConcreteDecoratorB::Operation()
{
Decorator::Operation();
OtherBehavior();
} void ConcreteDecoratorB::OtherBehavior()
{
std::cout<<"ConcreteDecoratorB OtherBehavior executed" << std::endl;
}
#include "Component.h"

int main()
{
std::shared_ptr<Component> pComponent(new ConcreteComponent); std::shared_ptr<Decorator> pDecoratorA(new ConcreteDecoratorA); pDecoratorA->SetComponent(pComponent); pDecoratorA->Operation(); std::shared_ptr<Decorator> pDecoratorB(new ConcreteDecoratorB); pDecoratorB->SetComponent(pComponent); pDecoratorB->Operation(); while();
}

7.测试结果

8.效果

  • 比静态继承更灵活 可以添加和分离方法,用装饰在运行时刻增加和删除职责。
  • 避免在层次结构高层的类有太多的特征
  • Decorator与它的Component不一样 Decorator是一个透明的包装。如果我们从对象表示的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。
  • 有许多小对象 有很多看上去很类似的小对象,这些对象仅仅在他们相互连接的方式上有所不同,而不是它们的类或它们的属性值有所不同。对于了解这些系统的人来说,很容易对它们进行定制,但是很难学习这些系统。

Decorator(装饰)-对象结构型模式的更多相关文章

  1. Decorator 装饰(结构型)

    Decorator 装饰(结构型) 一:描述: Decorator装饰模式是动态地给一个对象增加一些额外的功能职责特性. 来替换以前使用的继承来静态扩展对象的功能,避免子类的增多,做到更灵活: 注:和 ...

  2. 设计模式09: Decorator 装饰模式(结构型模式)

    Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...

  3. 组合模式/composite模式/对象结构型模式

    组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...

  4. 装饰模式(Decorator Pattern)--------结构型模式

    装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为.装饰模式降低类系统的耦合度,可以动态地增加或删除对象的职责,并使得需要装饰的具体构件类和具体装饰类可以独立变化,以便增加新的具体构件 ...

  5. Facade(外观)-对象结构型模式

    1.意图 为子系统中的一组接口提供一个一致的接口,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 2.动机 将一个系统划分成若干子系统有利于降低系统的复杂性.一个常见的设计目 ...

  6. Bridge模式——对象结构型模式

    今天看了Bridge模式,对其进行简单的总结,并给出几篇通俗易懂的文章链接. (一)意图--将抽象部分和它的实现部分分离,使它们都可以独立地变化. 适用于从多维度描述的类型,拆解开来,使其能沿着各维度 ...

  7. Bridge(桥接)-对象结构型模式

    1.意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 2.动机 在抽象类与它的实现之间起到桥梁作用,使它们可以独立地变化. 3.适用性 不希望在抽象和它的实现部分之间有一个固定的绑定关系. ...

  8. Adapter(适配器)-类对象结构型模式

    1.意图 将一个类接口转换成客户希望的另外一个接口.Adapter模式使那些原本不能一起工作的类,可以一起工作. 2.别名 包装器 Wrapper. 3.动机 一个应用可能会有一些类具有不同的接口,并 ...

  9. Proxy(代理)-对象结构型模式

    1.意图 为其它对象提供一种代理以控制对这个对象的访问. 2.别名 Surrogate. 3.动机 通过Proxy可以达到对一个对象的访问控制. 4.适用性 远程代理  为一个对象在不同地址空间提供局 ...

随机推荐

  1. html+css二级菜单制作!

    二级菜单!!<!DOCTYPE html<html lang="e<head> <meta charset="UTF-8"> < ...

  2. python 类中staticmethod,classmethod,普通方法

    1.staticmethod:静态方法和全局函数类似,但是通过类和对象调用. 2.classmethod:类方法和类相关的方法,第一个参数是class对象(不是实例对象).在python中class也 ...

  3. Jetty与Tomcat的区别 转

    Jetty与Tomcat的区别 由于没有研究过Tomcat,所以区别不好说,这里暂时就网上的一些言论和自己所了解到的一些总结下(摘自于许令波). Jetty 的架构从前面的分析可知,它的所有组件都是基 ...

  4. HTML 空格的表示符号 nbsp / ensp / emsp 的区别

    HTML 空格的表示符号 nbsp / ensp / emsp 的区别?     半角的不断行的空白格(推荐使用)    半角的空格    全角的空格

  5. fiddler web开发调试工具的使用

    fiddler使用场景: (1)开发环境host配置: 通常情况下,配置host需要改变系统文件很不方便,在多个开发环境下切换很低效 fiddler提供了相对高效的host配置方法 (2)前后端接口调 ...

  6. ecstore与淘宝sdk的autoload加载顺序问题

    ecstore使用spl_autoload_register实现类的自动加载,这个很大的方便我们不用每次都要手动的去include一些类和函数.不过这样会导致一些问题,比如说,有一些extension ...

  7. bzoj3822: 文学

    Description 巨酱和主席是一对好朋友.他们都很喜欢读书,经常一起阅读相关领域书籍,进行系统的学习.一天主席列出了一份列表,里面共 p 本书,其中不乏<约翰克里斯多夫>,<名 ...

  8. linux下nginx服务器域名指定目录

    一般,域名指定ip之后,需要在ip所在的机器去指定相应站点的目录,否则域名会不起作用: 下面说说linux下的nginx服务器指定目录的细节: 域名绑定目录的配置文件都放到这里: /usr/local ...

  9. Intellij Idea系列之导Jar包与编写单元测试(二)

     Intellij Idea系列之导Jar包与编写单元测试(二) 一.初衷 对于很多的初学者来说,Intellij如何导入jar包感到很迷惑,甚至在网上搜过相关文章之后还是云里雾里,本博客通过图文并茂 ...

  10. [MySQL] 忘记root账户密码怎么办

    一.缘由 由于各种原因,我们会忘记mysql的root密码. 二.解决办法 方法一:skip-grant-tables方式启动 1.停止mysql服 务 service mysqld stop 2.以 ...