装饰模式(Decorator)C++实现

装饰模式

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

 

意图:spa

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

 

适用性:指针

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

       二、处理那些能够撤销的职责。对象

       三、但愿为某个对象而不是一整个类添加一些功能时。blog

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

 

效果:接口

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

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

       三、会产生许多小对象。

       四、Decorator与Component不同,Decorator是一个透明的包装。若是咱们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差异的,所以,使用装饰时不该该依赖对象标识。

 

注意:

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

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

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

      

参与者:

Component

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

ConcreteComponent

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

Decorator

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

ConcreteDecorator

——向组件添加职责。

 

UML:

 

 

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

 

打印一行表格代码:

1 void print(char* str) 2 { 3     cout<<"├───────────────────────────────"<<endl 4         <<""<<str<<":"<<endl; 5 }

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

1 class absTable 2 { 3 public: 4 virtual void putTable() = 0; 5 };

定义具体的表格absTable(ConcreteComponent)

 1 class BaseTable:public absTable  2 {  3 public:  4     virtual void putTable()  5  {  6         print("姓名");  7         print("性别");  8         print("学历");  9         print("年龄"); 10         cout<<"└───────────────────────────────"<<endl; 11  } 12 };

定义抽象Decorator

 1 class Decorator:public absTable  2 {  3 public:  4     Decorator(absTable* concrateTb):mpAbsTable(concrateTb){}  5 
 6     virtual void putTable()  7  {  8         mpAbsTable->putTable();  9  } 10 private: 11     absTable* mpAbsTable; 12 };

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

 1 class EnglishDcrt:public Decorator  2 {  3 public:  4     EnglishDcrt(absTable* pTb):Decorator(pTb){}  5 
 6     virtual void putTable()  7  {  8         print("英语等级");  9  Decorator::putTable(); 10  } 11 };
 1 class CurWage:public Decorator  2 {  3 public:  4     CurWage(absTable* pTb):Decorator(pTb){}  5 
 6     virtual void putTable()  7  {  8         print("当前薪水");  9  Decorator::putTable(); 10  } 11 };
 1 class Experience:public Decorator  2 {  3 public:  4     Experience(absTable* pTb):Decorator(pTb){}  5 
 6     virtual void putTable()  7  {  8         print("项目经验");  9  Decorator::putTable(); 10  } 11 };

客户端代码:

 1 #include <iostream>
 2 #include "Decorator.h"
 3 
 4 using namespace std;  5 
 6 //动态的给一个对象添加一些额外的职责!  7 //层层包装,加强功能。这就是装饰模式的要旨!  8 //接口稳定不变!
 9 
10 void main() 11 { 12  BaseTable pro1; 13     cout<<"初始表格:"<<endl<<endl; 14  pro1.putTable(); 15 
16     cout<<"新表格1:"<<endl<<endl; 17     EnglishDcrt eng(&pro1); 18  eng.putTable(); 19 
20     cout<<"新表格2:"<<endl<<endl; 21     CurWage wg(&eng); 22  wg.putTable(); 23 
24     cout<<"新表格3:"<<endl<<endl; 25     Experience ex(&wg); 26  ex.putTable(); 27 }

部分结果:

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

相关文章
相关标签/搜索