層層包裝,加強功能。這就是裝飾模式的要旨!裝飾器模式就是基於對象組合的方式,能夠很靈活的給對象添加所須要的功能。它把須要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象。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 }
部分結果:
這樣咱們實現了項目經驗、當前薪水、英語等級的自由組合,固然還能夠添加更多的屬性。