裝飾模式(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 }

部分結果:

這樣咱們實現了項目經驗、當前薪水、英語等級的自由組合,固然還能夠添加更多的屬性。

相關文章
相關標籤/搜索