装饰者模式及C++实现
装饰者模式
时常会遇到这样一种情况,我已经设计好了一个接口,并且也有几个实现类,但是这时我发现我设计的时候疏忽了,忘记了一些功能,或者后来需求变动要求加入一些功能,最简单的做法就是修改接口,添加函数,然后继承类中都相应的添加实现,这样做倒也没什么问题,但是如果这种变化来个好几次或者继承类非常多,那工作量可就大了。
这时大神们就发明了装饰者模式,在不修改现在有接口和实现类的基础上实现功能或者状态的添加。
从类图上看,ConcreteComponent是Component原有的继承类,而Decorator装饰者类也继承与Component,这样的是让Decorator的子类也可以方便的添加Component,而不用每个子类里面都去包含一次Component。(我的理解)
这样客户端使用的时候只需要知道ConcreteDecorator就可以直接调用Decorator的operation方法了,至于operation方法是怎么实现的以及使用的Component的哪一个子类是不需要关心的,而且添加的方法addBehavior也可以直接使用。
客户端就无法依赖于抽象了,如果addBehavior的实现方法要变了,比较好的是添加新的ConcreteDecorator子类,或者继承这个ConcreteDecorator重新实现addBehavior。

常用的情况
如果需要添加新功能,但又不想修改定义好的接口或者抽象类,那么这时候就比较适合装饰模式,例如很多图形系统中的组件,就可以使用装饰模式,来让新的组件在继承现在功能的基础上添加新的功能。
装饰模式一般是针对接口或者抽象类的变化,如果是具体实现类的变化,则要考虑适用哪种模式。
优点
1.可以不用修改原有的接口,就可以实现新功能的添加。
2.装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。
缺点
1.复杂性增加,装饰者模式会导致许多小类的产生。
C++代码实现
#ifndef _COMPONENT_H_
#define _COMPONENT_H_ class Component
{
public:
Component();
virtual ~Component(); virtual void operation() = ;
}; class ConcreteComponent: public Component
{
public:
ConcreteComponent();
~ConcreteComponent(); void operation();
}; #endif
#include "Component.h"
#include <stdio.h> Component::Component()
{ } Component::~Component()
{ } ConcreteComponent::ConcreteComponent()
{ } ConcreteComponent::~ConcreteComponent()
{ } void ConcreteComponent::operation()
{
fprintf(stderr, "ConcreteComponent's operation!\n");
}
#ifndef _DECORATOR_H_
#define _DECORATOR_H_ #include "Component.h" class Decorator: public Component
{
public:
Decorator();
virtual ~Decorator(); virtual void operation();
virtual void setComponent(Component* pComponent); protected:
Component* mComponent;
}; class ConcreteDecorator: public Decorator
{
public:
ConcreteDecorator();
virtual ~ConcreteDecorator(); virtual void addBehavior();
}; #endif
Decorator.h
#include "Decorator.h"
#include <stdio.h> Decorator::Decorator()
{ } Decorator::~Decorator()
{ } void Decorator::operation()
{
mComponent->operation();
} void Decorator::setComponent(Component* pComponent)
{
this->mComponent = pComponent;
} ConcreteDecorator::ConcreteDecorator()
{ } ConcreteDecorator::~ConcreteDecorator()
{ } void ConcreteDecorator::addBehavior()
{
fprintf(stderr, "ConcreteDecorator's addBehavior!\n");
}
Decorator.cpp
#include "Decorator.h" int main()
{
Component* pComponent = new ConcreteComponent();
ConcreteDecorator* pConDecorator = new ConcreteDecorator();
pConDecorator->setComponent(pComponent);
pConDecorator->operation();
pConDecorator->addBehavior();
return ;
}
client.cpp
g++ -o client client.cpp Component.cpp Decorator.cpp
运行结果

装饰者模式及C++实现的更多相关文章
- 装饰者模式 Decoration
1.什么是装饰者模式 动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活.当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列 ...
- JAVA装饰者模式(从现实生活角度理解代码原理)
装饰者模式可以动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 该模式的适用环境为: (1)在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- 设计模式(九)装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- PHP 装饰器模式
装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...
- C#设计模式-装饰者模式
在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).Access ...
- Java 的设计模式之一装饰者模式
刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...
- 《Head First 设计模式》之装饰者模式
作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...
- DecoratorPattern(装饰器模式)
/** * 装饰者模式 * @author TMAC-J * 总的来说,装饰者模式就是继承的应用 */ public class DecoratorPattern { interface Beans{ ...
- 设计模式-装饰器模式(Decrator Model)
文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...
随机推荐
- Python 定期检查Build_setting的编译情况
#!/usr/bin/python #_*_ coding:utf-8 _*_ import time from email.MIMEText import MIMEText from email.M ...
- ruby里面module和class的区别
一句话概括,就是 class可以实例化 module不可以 别的都一样 关于继承的一点区别 class是使用<作为继承的关键字,只支持单继承 module是使用include来做实例继承(实例化 ...
- 黄聪:WIN7下回收站不小心删除的文件怎么恢复,免费数据恢复软件下载
上网找了半天,大多数是收费的,总算找到一款免费的,已经帮我恢复了数据了,在此分享给大家. 注意:只能恢复7天内的,而且数据误删了,就尽量不要再修改你那个盘符的数据了,免得覆盖了! 我用的数据恢复软件R ...
- LeetCode 177. Nth Highest Salary
https://leetcode.com/problems/nth-highest-salary/description/ Write a SQL query to get the nth highe ...
- SecureCRT 上传/下载文件到Linux服务器
1. 安装上传/.下载软件 a) cd /tmp wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz tar zxvf lrzsz-0. ...
- django单表操作,增、删、改、查
一.实现:增.删.改.查 1.获取所有数据显示在页面上 model.Classes.object.all(),拿到数据后,渲染给前端;前端通过for循环的方式,取出数据. 目的:通过classes(班 ...
- c# 之 new 关键字
1.实例化变量 DataTable dt = new DataTable(); 2.调用构造函数 class CoOrds { public int x, y; // 实例构造函数(默认构造函数) ...
- 启动tomcat报:No Spring WebApplicationInitializer types detected on classpath
提示找不到web容器,有可能是未加载到spring配置文件,可能是配置文件所在的文件夹未发布或者发布的路径不对导致无法找到 右键web项目,选择properties 查看Deployment Asse ...
- Unix高级编程Note1
[Unix Notes] 1./etc/passwd 2.extern int errno; 3.限制, limit.h 4.文件原子操作:O_EXCL & O_CREAT 5.stat操作 ...
- python之private variable
[python之private variable] Since there is a valid use-case for class-private members (namely to avoid ...