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装饰模式(结构模式)
子类复子类,子类何其多 假如我们需要为游戏中开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合中为其增加以下一种或多种功能:比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等等. 动机 ...
随机推荐
- UVa 673 平衡的括号
题意:给出包含"()"和"[]"的括号序列,判断是否合法. 用栈来完成,注意空串就行. #include<iostream> #include< ...
- iptables的扩展匹配
iptables的匹配条件 一.通用匹配:-s.-d.-p.-i.-o 二.扩展匹配 1.隐含扩展:使用-p{tcp|udp|icmp}指定某特定协议后,自动能够对协议进行扩展 -p tcp --dp ...
- CentOS7 安装 net-speeder 提升 VPS 网络性能
参考:http://blog.csdn.net/u010027419/article/details/46129639 1.安装依赖库 先安装epel源 rpm -Uvh http://dl.fedo ...
- 改进:js修改iOS微信浏览器的title
问题简介 前端入门没多久,可能连入门也不算,最近网上流行各自书籍改名,什么<前端开发,从入门到放弃>,<Android开发,从入门到改行>之类的,程序员真是个爱自嘲的群体,但我 ...
- mybatis generator使用(基于maven)
1.添加maven依赖 <dependency> <groupId>org.mybatis.generator</groupId> <artifactId&g ...
- 内网透过公网nginx和vpn实现微信接口调试
条件: 1.公网IP开放80/443端口 2.vpn,我熟悉openvpn 3.nginx反向代理 1.在公网服务器上装nginx和vpnserver 2.本地调试电脑装vpnclient,mac o ...
- api接口验证shal()
就安全来说,所有客户端和服务器端的通信内容应该都要通过加密通道(HTTPS)传输,明文的HTTP通道将会是man-in-the- middle及其各种变种攻击的温床.所谓man-in-the-midd ...
- Selenium2入门(一)简介
Selenium 是一款有名的 Web 应用程序测试框架,用于进行功能测试.新版本 Selenium 2 结合了 Selenium 1 和 WebDriver(Selenium 的并行项目)中的最佳特 ...
- ecstore-lnmp环境下crontab不执行原因
因为lnmp.org默认禁止了proc_open函数,需要开启 开启后 lnmp restart ==== contab还是用crontab -e好,有些用www用户的似乎执行不了
- jQuery EasyUI:根据数据库内容生成适合于easyui-tree的JSON数据格式
1,jQuery EasyUI中easyui-tree特定的JSON数据格式 [ {"id":1,"text":"某公司","ch ...