水平有限,請多指正!
裝飾者模式(Decorator)樣本
例子改編自《設計者模式解析(第二版)》214頁,人民郵電出版社
意圖:動態給一個對象添加職責;即提供了“隨插即用”方法,不用重新編譯已有部分。
問題:要使用的對象將執行所需的準系統。但是,可能需要為這個對像添加某些功能,這些附加的功能可能發生在對象的準系統之前或之後。
解決方案:可以無需建立子類而擴充一個對象的功能
優點:類的階層大小和複雜度有了很大程度的降低
缺點:
1)如果裝飾者本身是被裝飾的,那麼訪問裝飾模式中引進的特性將是非常困難的甚至是危險的。
2)系統對裝飾者的使用順序是敏感的。
附:顯然,如果要更改被裝飾者的準系統的情況是不能用裝飾者模式的。
參考文獻:
[1]《設計者模式解析(第二版)》,人民郵電出版社,Alan Shalloway等著,徐言生譯
[2]《設計模式初學者指南》,機械工業出版社,Allen Holub著,徐迎曉譯
對樣本的描述:
1)具體組件SalesTicket(即被裝飾者)實現準系統(即列印票據本文),需要給它加個表頭和表尾,於是用兩個具體裝飾類Header和Footer完成附加功能。
2)例子改編自參考文獻[1],不明白可以看。
3)使用編譯器vc6.0通過。
#include <iostream> </p><p>using namespace std;</p><p>//=================================================<br />class Component //抽象組件,即對象的介面<br />{<br />public:<br /> virtual void prtTicket() = 0;<br />};<br />//=================================================<br />//具體組件,即被裝飾者<br />class SalesTicket: public Component<br />{<br />public:<br /> //SalesTicket()<br /> //{<br /> // cout<<"構造具體組件SalesTicket/n"<<endl;<br /> //} </p><p> void prtTicket()<br /> {<br /> cout<<"具體組件SalesTicket列印票據本文/n"<<endl;<br /> }<br />};<br />//=================================================<br />//裝飾者(也是抽象組件的子類)<br />class TicketDecorator: public Component<br />{<br />private:<br /> Component* pMyTrailer;//抽象組件作為成員變數 </p><p>public:<br /> TicketDecorator(Component& myComponent)//實際使用時,傳入建構函式的是具體組件(即被裝飾者)<br /> {<br /> //cout<<"構造裝飾者TicketDecorator/n"<<endl;<br /> pMyTrailer = NULL;<br /> pMyTrailer = &myComponent;<br /> }</p><p> void callTrailer()<br /> {<br /> if(pMyTrailer != NULL)<br /> pMyTrailer->prtTicket();<br /> }</p><p> //是否需要釋放pMyTrailer??????<br /> //如果遵循“誰申請,誰釋放”的原則,則不需要<br />};<br />//=================================================<br />//具體裝飾者Header(是裝飾者的子類)<br />//功能:列印表頭<br />class Header: public TicketDecorator<br />{<br />public:<br /> Header(Component& myComponent):TicketDecorator(myComponent)<br /> {<br /> //cout<<"構造具體裝飾者Header/n"<<endl;<br /> }</p><p> void prtTicket()<br /> {<br /> //功能:在表的前面加個頭部 </p><p> //注意這行代碼的位置,在callTrailer()之前<br /> //這是裝飾者添加的功能<br /> cout<<"具體裝飾者Header列印表頭/n"<<endl;</p><p> TicketDecorator::callTrailer();<br /> }<br />};</p><p>//具體裝飾者Footer(是裝飾者的子類)<br />//功能:列印表尾<br />class Footer: public TicketDecorator<br />{<br />public:<br /> Footer(Component& myComponent):TicketDecorator(myComponent)<br /> {<br /> //cout<<"構造具體裝飾者Footer/n"<<endl;<br /> }</p><p> void prtTicket()<br /> {<br /> //功能:在表的後面加個尾部 </p><p> TicketDecorator::callTrailer();</p><p> //注意這行代碼的位置,在callTrailer()之後<br /> //這是裝飾者添加的功能<br /> cout<<"具體裝飾者Footer列印表尾/n"<<endl;<br /> }<br />};<br />//=================================================<br />class Factory//工廠<br />{<br />public:<br /> Component* m_pMyComponent;<br /> Component* m_pMyFooter;<br /> Component* m_pMyHeader;</p><p> Factory()<br /> {<br /> Component* m_pMyComponent = NULL;<br /> Component* m_pMyFooter = NULL;<br /> Component* m_pMyHeader = NULL;<br /> }</p><p> Component* getComponent()<br /> {<br /> m_pMyComponent = new SalesTicket();<br /> m_pMyFooter = new Footer(*m_pMyComponent);<br /> m_pMyHeader = new Header(*m_pMyFooter);</p><p> return m_pMyHeader;//返回最後一個指標<br /> }</p><p> ~Factory()//別忘了釋放空間<br /> {</p><p> delete m_pMyComponent;<br /> delete m_pMyFooter;<br /> delete m_pMyHeader;<br /> }<br />};<br />//================================================= </p><p>int main(int argc, char* argv[])<br />{<br /> //使用<br /> Factory myFactory;<br /> Component* pMyComponent = myFactory.getComponent();<br /> pMyComponent->prtTicket();//列印 </p><p> return 0;<br />}</p><p>