原文地址:http://www.jellythink.com/archives/171ios
在實際開發時,你有沒有碰到過這種問題;開發一個類,封裝了一個對象的核心操做,而這些操做就是客戶使用該類時都會去調用的操做;而有一些非核心的操做,可能會使用,也可能不會使用;如今該怎麼辦呢?shell
在GOF的《設計模式:可複用面向對象軟件的基礎》一書中對裝飾模式是這樣說的:動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator模式相比生成子類更爲靈活。windows
裝飾模式可以實現動態的爲對象添加功能,是從一個對象外部來給對象添加功能。一般給對象添加功能,要麼直接修改對象添加相應的功能,要麼派生對應的子類來擴展,抑或是使用對象組合的方式。顯然,直接修改對應的類這種方式並不可取。在面向對象的設計中,而咱們也應該儘可能使用對象組合,而不是對象繼承來擴展和複用功能。裝飾器模式就是基於對象組合的方式,能夠很靈活的給對象添加所須要的功能。裝飾器模式的本質就是動態組合。動態是手段,組合纔是目的。總之,裝飾模式是經過把複雜的功能簡單化,分散化,而後再運行期間,根據須要來動態組合的這樣一個模式。它使得咱們能夠給某個對象而不是整個類添加一些功能。設計模式
Component:定義一個對象接口,能夠給這些對象動態地添加職責;ide
ConcreteComponent:定義一個具體的Component,繼承自Component,重寫了Component類的虛函數;函數
Decorator:維持一個指向Component對象的指針,該指針指向須要被裝飾的對象;並定義一個與Component接口一致的接口;學習
ConcreteDecorator:向組件添加職責。網站
1 /* 2 ** FileName : DecoratorPatternDemo 3 ** Author : Jelly Young 4 ** Date : 2013/12/19 5 ** Description : More information, please go to http://www.jellythink.com 6 */ 7 #include <iostream> 8 using namespace std; 9 class Component 10 { 11 public: 12 virtual void Operation() = 0; 13 }; 14 class ConcreteComponent : public Component 15 { 16 public: 17 void Operation() 18 { 19 cout<<"I am no decoratored ConcreteComponent"<<endl; 20 } 21 }; 22 class Decorator : public Component 23 { 24 public: 25 Decorator(Component *pComponent) : m_pComponentObj(pComponent) {} 26 void Operation() 27 { 28 if (m_pComponentObj != NULL) 29 { 30 m_pComponentObj->Operation(); 31 } 32 } 33 protected: 34 Component *m_pComponentObj; 35 }; 36 class ConcreteDecoratorA : public Decorator 37 { 38 public: 39 ConcreteDecoratorA(Component *pDecorator) : Decorator(pDecorator){} 40 void Operation() 41 { 42 AddedBehavior(); 43 Decorator::Operation(); 44 } 45 void AddedBehavior() 46 { 47 cout<<"This is added behavior A."<<endl; 48 } 49 }; 50 class ConcreteDecoratorB : public Decorator 51 { 52 public: 53 ConcreteDecoratorB(Component *pDecorator) : Decorator(pDecorator){} 54 void Operation() 55 { 56 AddedBehavior(); 57 Decorator::Operation(); 58 } 59 void AddedBehavior() 60 { 61 cout<<"This is added behavior B."<<endl; 62 } 63 }; 64 int main() 65 { 66 Component *pComponentObj = new ConcreteComponent(); 67 Decorator *pDecoratorAOjb = new ConcreteDecoratorA(pComponentObj); 68 pDecoratorAOjb->Operation(); 69 cout<<"============================================="<<endl; 70 Decorator *pDecoratorBOjb = new ConcreteDecoratorB(pComponentObj); 71 pDecoratorBOjb->Operation(); 72 cout<<"============================================="<<endl; 73 Decorator *pDecoratorBAOjb = new ConcreteDecoratorB(pDecoratorAOjb); 74 pDecoratorBAOjb->Operation(); 75 cout<<"============================================="<<endl; 76 delete pDecoratorBAOjb; 77 pDecoratorBAOjb = NULL; 78 delete pDecoratorBOjb; 79 pDecoratorBOjb = NULL; 80 delete pDecoratorAOjb; 81 pDecoratorAOjb = NULL; 82 delete pComponentObj; 83 pComponentObj = NULL; 84 }
以前總結了C++設計模式——橋接模式;你會發現,兩者都是爲了防止過分的繼承,從而形成子類氾濫的狀況。那麼兩者之間的主要區別是什麼呢?橋接模式的定義是將抽象化與實現化分離(用組合的方式而不是繼承的方式),使得二者能夠獨立變化。能夠減小派生類的增加。若是光從這一點來看的話,和裝飾者差很少,但二者仍是有一些比較重要的區別:spa
裝飾模式重點在裝飾,對核心功能的裝飾做用;將繼承中對子類的擴輾轉化爲功能類的組合,從而將須要對子類的擴輾轉嫁給用戶去進行調用組合,用戶如何組合由用戶去決定。我在學習裝飾模式時,就是重點分析了「裝飾」這個詞,咱們都知道,裝飾是在一個核心功能上添加一些附屬功能,從而讓核心功能發揮更大的做用,可是最終它的核心功能是不能丟失的。這就比如咱們進行windows shell開發時,咱們是對windows的這層殼進行了功能的裝飾,從而實現了咱們須要的一些裝飾功能,可是最終的功能仍是由windows shell去完成。這就比如,咱們的裝飾就是給核心功能添加了一層外衣,讓它看起來更漂亮和完美。設計