C++设计模式-Decorator装饰模式
Decorator装饰模式
作用:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
UML图如下:

Component是定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为 的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为 时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
代码如下:
Decorator.h
#ifndef _DECORATOR_H_
#define _DECORATOR_H_ //Component抽象类,定义该类对象的接口
class Component
{
public:
virtual ~Component();
virtual void Operation()=;
protected:
Component();
}; //ConcreteDecorator:具体的Component对象,可以给该对象动态 添加职责
class ConcreteComponent:public Component
{
public:
ConcreteComponent();
~ConcreteComponent();
virtual void Operation();
}; //Decorator:装饰抽象类,继承自Component
class Decorator:public Component
{
public:
Decorator(Component* com);
void SetComponent(Component* com);
virtual ~Decorator();
virtual void Operation();
protected:
Component* _com;
}; //ConcreteDecorator就是具体的装饰对象之一,起到给Component添加职责的功能
class ConcreteDecoratorA:public Decorator
{
public:
ConcreteDecoratorA(Component* com);
~ConcreteDecoratorA();
virtual void Operation();
void AddBehavorA();
}; //ConcreteDecorator就是具体的装饰对象之二,起到给Component添加职责的功能
class ConcreteDecoratorB:public Decorator
{
public:
ConcreteDecoratorB(Component* com);
~ConcreteDecoratorB();
virtual void Operation();
void AddBehavorB();
}; //ConcreteDecorator就是具体的装饰对象之三,起到给Component添加职责的功能
class ConcreteDecoratorC:public Decorator
{
public:
ConcreteDecoratorC(Component* com);
~ConcreteDecoratorC();
virtual void Operation();
void AddBehavorC();
}; //ConcreteDecorator就是具体的装饰对象之四,起到给Component添加职责的功能
class ConcreteDecoratorD:public Decorator
{
public:
ConcreteDecoratorD(Component* com);
~ConcreteDecoratorD();
virtual void Operation();
void AddBehavorD();
}; //只添加一种装饰,则不用抽象出装饰基类
class DecoratorOnlyOne:public Component
{
public:
DecoratorOnlyOne(Component* com);
~DecoratorOnlyOne();
virtual void Operation();
void AddBehavor();
private:
Component* _com;
}; //如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
//略
#endif
Decorator.cpp
#include "Decorator.h"
#include <iostream> using namespace std; Component::Component()
{} Component::~Component()
{
cout << "~Component" << endl;
} ConcreteComponent::ConcreteComponent()
{} ConcreteComponent::~ConcreteComponent()
{
cout << "~ConcreteComponent" << endl;
} void ConcreteComponent::Operation()
{
cout << "原职责:ConcreteComponent::Operation" << endl;
} Decorator::Decorator(Component* com)
{
this->_com = com;
} void Decorator::SetComponent(Component* com)
{
this->_com = com;
} Decorator::~Decorator()
{
cout << "~Decorator" << endl;
delete this->_com;
this->_com = NULL;
} void Decorator::Operation()
{} ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com)
{} ConcreteDecoratorA::~ConcreteDecoratorA()
{
cout << "~ConcreteDecoratorA" << endl;
} void ConcreteDecoratorA::Operation()
{
this->_com->Operation();
//附加职责A
this->AddBehavorA();
} void ConcreteDecoratorA::AddBehavorA()
{
cout << "附加职责A:ConcreteDecoratorA::AddBehavorA" << endl;
} ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com)
{} ConcreteDecoratorB::~ConcreteDecoratorB()
{
cout << "~ConcreteDecoratorB" << endl;
} void ConcreteDecoratorB::Operation()
{
this->_com->Operation();
//附加职责B
this->AddBehavorB();
} void ConcreteDecoratorB::AddBehavorB()
{
cout << "附加职责B:ConcreteDecoratorB::AddBehavorB" << endl;
} ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com)
{} ConcreteDecoratorC::~ConcreteDecoratorC()
{
cout << "~ConcreteDecoratorC" << endl;
} void ConcreteDecoratorC::Operation()
{
this->_com->Operation();
//附加职责C
this->AddBehavorC();
} void ConcreteDecoratorC::AddBehavorC()
{
cout << "附加职责C:ConcreteDecoratorC::AddBehavorC" << endl;
} ConcreteDecoratorD::ConcreteDecoratorD(Component* com):Decorator(com)
{} ConcreteDecoratorD::~ConcreteDecoratorD()
{
cout << "~ConcreteDecoratorD" << endl;
} void ConcreteDecoratorD::Operation()
{
this->_com->Operation();
//附加职责D
this->AddBehavorD();
} void ConcreteDecoratorD::AddBehavorD()
{
cout << "附加职责D:ConcreteDecoratorD::AddBehavorD" << endl;
} //**************只添加一种修饰******************
DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com)
{
} DecoratorOnlyOne::~DecoratorOnlyOne()
{
cout << "~DecoratorOnlyOne" << endl;
delete this->_com;
this->_com = NULL;
} void DecoratorOnlyOne::Operation()
{
this->_com->Operation();
this->AddBehavor();
} void DecoratorOnlyOne::AddBehavor()
{
cout << "附加唯一职责:DecoratorOnlyOne::AddBehavor" << endl;
}
main.cpp
#include "Decorator.h"
#include <iostream> using namespace std;
int main()
{
Component* pCom = new ConcreteComponent(); //要装饰的对象
Decorator* pDec = NULL;
pDec = new ConcreteDecoratorA(pCom); //给装饰对象附加职责A
pDec = new ConcreteDecoratorB(pDec); //给装饰对象附加职责B
pDec = new ConcreteDecoratorC(pDec); //给装饰对象附加职责C
pDec = new ConcreteDecoratorD(pDec); //给装饰对象附加职责D
pDec->Operation(); cout << "-------------------------------" << endl; //只添加一种修饰
Component* pCom1 = new ConcreteComponent();
DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1);
pDec1->Operation(); cout << "-------------------------------" << endl; delete pDec;
cout << "-------------------------------" << endl; delete pDec1; return ;
}
运行结果:
Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法了。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过Decorator模式来解决,你可以一步步添加新的职责。
C++设计模式-Decorator装饰模式的更多相关文章
- c++ 设计模式6 (Decorator 装饰模式)
4. “单一职责”类模式 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式代表: Decorato ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式之装饰模式(Decorator)摘录
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/fengbingchun/article/details/29237955 23种GOF设计模式一般分 ...
- 设计模式09: Decorator 装饰模式(结构型模式)
Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- java设计模式—Decorator装饰者模式
一.装饰者模式 1.定义及作用 该模式以对客户端透明的方式扩展对象的功能. 2.涉及角色 抽象构件角色:定义一个抽象接口,来规范准备附加功能的类. 具体构件角色:将要被附加功能的类,实现抽象 ...
- C#设计模式之八装饰模式(Decorator Pattern)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第三个模式,该模式是[装饰模式],英文名称:Decorator Pattern.我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧 ...
- GOF23设计模式之装饰模式(decorator)
一.装饰模式概述 (1)动态的为一个对象增加新的功能. (2)装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能. 使用对象的关联关系代替继承关系,更加灵活,同时避免类型体 ...
- 设计模式学习之路——Decorator装饰模式(结构模式)
子类复子类,子类何其多 假如我们需要为游戏中开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合中为其增加以下一种或多种功能:比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等等. 动机 ...
随机推荐
- POJ 2251 BFS(简单)
一道三维的BFS Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24003 Accepted: 9 ...
- ubantu svn 安装、卸载、配置hooks
1.安装之前先看是否已经安装了 svn -version 若已经安装会有以下提示,若没有安装,进行下一步 若想卸载了执行命令 ( sudo apt-get remove --purge subvers ...
- Java中抽象类和接口
抽象类: 为什么要用抽象类? 1.父类的方法好多情况下是没有内容的.例如:USB是一个父类,里面的方法的函数体是可以不写,通过子类可以重写. 2.万一子类没有重写正确,是没有没有提示的.例如:父类中函 ...
- Android 中算法问题
1:冒泡排序: 冒泡排序的思路: 相邻的两个数进行比较 (1):首先需要连个for 循环 (2):最外层for 循环控制最里面 for 循环的循环次数 (3):通过设置中间参数的方式进行交换 (4): ...
- 在MyEclipse和Eclipse中添加Hibernate开发工具
一.插件准备 MyEclipse需要的插件:HibernateTools-3.2.4.zip Eclipse需要的插件:jbosstools-4.2.3.Final_2015-03-26_22-41- ...
- vim下打造python编辑器
在前面文章中介绍的关于vim基础插件之上加上一款专门为读写python程序的插件-Python-mode. 顾名思义,就是让vim在python模式下运行.这里介绍这款插件的功能以及如何使用. 本文主 ...
- JavaScript分离代码理解
window.onload=prepareLinks; //页面加载触发onload事件 function prepareLinks(){ //定义函数 var links=document.getE ...
- Baidu set to lose leading role in digital advertising _china daily
advertising: n,广告 Online search giant Baidu Inc is set to loset its top spot in the nation's booming ...
- OpenGL投影矩阵
概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐 ...
- JDK、JRE、JVM
首先来说一下JDKJDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Env ...