装饰模式

层层包装,增强功能。这就是装饰模式的要旨!装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。它把需要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。

意图:

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

适用性:

1、在不影响其它对象的情况下,以动态、透明的方式给单个对象添加职责。

2、处理那些可以撤销的职责。

3、希望为某个对象而不是一整个类添加一些功能时。

4、当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

效果:

1、比静态继承更为灵活。继承机制会产生许多新类,增加了系统的复杂度。而装饰可以使你对一些职责进行混合和匹配。

2、避免在层次结构高层的类有太多的特征。扩展一个复杂类的时候,很可能会暴露出与添加职责无关的细节。你可以定义一个简单的类,并且用装饰逐渐的添加功能。

3、会产生许多小对象。

4、Decorator与Component不一样,Decorator是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。

注意:

1、接口的一致性。装饰对象的接口必须与它所装饰的Component的接口是一致的。

2、省略抽象的Docorator类。当你仅需要添加一个职责的时,没有必要定义抽象Decorator类。你常常需要处理显存的类层次结构而不是设计一个新系统,这时你可以把Decorator向Component转发请求的职责合并到ConcreteDecorator中。

3、保持Component类的简单性。为了保证接口的一致性,组件和装饰必须有一个共同的Component父类。因此保持这个类的简单些是很重要的。

参与者:

Component

——定义一个对象接口,可以给这些对象动态的添加职责。

ConcreteComponent

——定义一个对象,可以给这个对象添加一些职责。

Decorator

——维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

ConcreteDecorator

——向组件添加职责。

UML:

代码实现:在控制台打印如下表格,基本的姓名、年龄、学历、性别必须拥有,其它如英语等级等属性自由添加。

打印一行表格代码:

void print(char* str)
{
cout<<"├───────────────────────────────"<<endl
<<"│"<<str<<":"<<endl;
}

定义一个抽象基类absTable(Component)

class absTable
{
public:
virtual void putTable() = ;
};

定义具体的表格absTable(ConcreteComponent)

class BaseTable:public absTable
{
public:
virtual void putTable()
{
print("姓名");
print("性别");
print("学历");
print("年龄");
cout<<"└───────────────────────────────"<<endl;
}
};

定义抽象Decorator

class Decorator:public absTable
{
public:
Decorator(absTable* concrateTb):mpAbsTable(concrateTb){} virtual void putTable()
{
mpAbsTable->putTable();
}
private:
absTable* mpAbsTable;
};

定义具体的装饰EnglishDcrt、CurWage、Experience(ConcreteDecoratorA、B、C)

class EnglishDcrt:public Decorator
{
public:
EnglishDcrt(absTable* pTb):Decorator(pTb){} virtual void putTable()
{
print("英语等级");
Decorator::putTable();
}
};
class CurWage:public Decorator
{
public:
CurWage(absTable* pTb):Decorator(pTb){} virtual void putTable()
{
print("当前薪水");
Decorator::putTable();
}
};
class Experience:public Decorator
{
public:
Experience(absTable* pTb):Decorator(pTb){} virtual void putTable()
{
print("项目经验");
Decorator::putTable();
}
};

客户端代码:

#include <iostream>
#include "Decorator.h" using namespace std; //动态的给一个对象添加一些额外的职责!
//层层包装,增强功能。这就是装饰模式的要旨!
//接口稳定不变! void main()
{
BaseTable pro1;
cout<<"初始表格:"<<endl<<endl;
pro1.putTable(); cout<<"新表格1:"<<endl<<endl;
EnglishDcrt eng(&pro1);
eng.putTable(); cout<<"新表格2:"<<endl<<endl;
CurWage wg(&eng);
wg.putTable(); cout<<"新表格3:"<<endl<<endl;
Experience ex(&wg);
ex.putTable();
}

部分结果:

这样我们实现了项目经验、当前薪水、英语等级的自由组合,当然还可以添加更多的属性。

最新文章

  1. iOS学习15之OC集合
  2. mariadb数据库忘记密码如何找回
  3. wdcp 下apache模式开启https访问,支持多站点
  4. SendInput模拟Win(VK_LWIN)键的问题
  5. PHP笔记(PHP高级篇)
  6. Excel操作增强包
  7. JQuery事件的绑定
  8. vim 快捷键大全
  9. DbConnectionFactory 数据库连接
  10. 最简单的ajax调用webservice
  11. Xcode 使用技巧
  12. Kafka 1.0.0集群增加节点
  13. python内置函数整理
  14. jmeter打开其他设备转过来的历史脚本出现报错
  15. unity 数学公式
  16. pssh,pdsh,mussh,cssh,dsh运维工具介绍
  17. Redis面试题及分布式集群
  18. 20145324王嘉澜《网络对抗技术》MSF基础应用
  19. ios之开发屏幕适配和系统版本适配
  20. Java WebService 知识点汇总

热门文章

  1. (转)淘淘商城系列——Solr集群搭建
  2. iconfont
  3. H5-data属性的一个问题
  4. git_仓库
  5. CentOS 7.2.1511编译安装Nginx1.10.1+MySQL5.7.15+PHP7.0.11
  6. python爬虫07 | 有了 BeautifulSoup ,妈妈再也不用担心我的正则表达式了
  7. 批量重命名B站下载文件
  8. 【2】Django安装
  9. EditorLineEnds.ttr的困扰
  10. 【[Offer收割]编程练习赛15 C】过河问题