裝飾模式
動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比產生子類更為靈活。
裝飾模式是為已有功能動態地添加更多功能的一種方式。
裝飾模式把每個要裝飾的功能放在單獨的類中,並讓這個類包含它所要裝飾的對象,因此,當需要執行特殊行為時,客戶代碼就可以在運行時根據需要有選擇地,按順序地使用裝飾功能封裝對象了。
裝飾模式的優點是:
1.把類中的裝飾功能從類中搬移去除,這樣可以簡化原有的類。
2.有效地把類的核心職責和裝飾功能區分開了。而且可以去除相關類中重複的裝飾邏輯。
還是讓代碼來體現裝飾模式的好處吧。
V1.0版 簡單地給人搭配一下服飾
Person類<br />#include <iostream><br />using namespace std;</p><p>class Person<br />{<br />private:<br />const char* name;<br />public:<br />Person(const char * name)<br />{<br />this->name = name;<br />}</p><p>void WearTShirts()<br />{<br />cout<<"大T恤 ";<br />}</p><p>void WearBigTrouser()<br />{<br />cout<<"垮褲 ";<br />}</p><p>void WearSneakers()<br />{<br />cout<<"破球鞋 ";<br />}</p><p> void WearSuit()<br />{<br />cout<<"西裝 ";<br />}</p><p>void WearTie()<br />{<br />cout<<"領帶 ";<br />}</p><p>void WearLeatherShoes()<br />{<br />cout<<"皮鞋 ";<br />}</p><p> void Show()<br />{<br />cout<<"裝扮的"<< name;<br />}<br />};<br />命令列輸出<br />#include <iostream><br />#include "stdafx.h"<br />#include "person.h"</p><p>int _tmain(int argc, _TCHAR* argv[])<br />{<br />Person* xc = new Person("小菜");<br />cout<<"第一種裝扮:";</p><p>xc->WearTShirts();<br />xc->WearBigTrouser();<br />xc->WearSneakers();<br />xc->Show();</p><p>cout<<endl;<br />cout<<"第二種裝扮:";</p><p>xc->WearSuit();<br />xc->WearTie();<br />xc->WearLeatherShoes();<br />xc->Show();</p><p>cin.get();<br />return 0;<br />}<br />
如果需要增加“超人”裝扮,就得修改Person類,違背了開放-封閉原則
V2.0版本
Person類<br />#include <iostream><br />using namespace std;</p><p>class Person<br />{<br />private:<br />const char* name;<br />public:<br />Person(const char * name)<br />{<br />this->name = name;<br />}<br />public:<br />void Show()<br />{<br />cout<<"裝扮的"<< name;<br />}</p><p>};<br />服飾類<br />class Finery<br />{<br />public:<br />virtual void Show(){};<br />};<br />各個裝飾類<br />/大T恤<br />class TShirts : public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"大T恤 ";<br />}<br />};</p><p>//垮褲<br />class BigTrouser : public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"垮褲 ";<br />}<br />};</p><p>//破球鞋<br />class Sneakers :public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"破球鞋 ";<br />}</p><p>};</p><p>//西裝<br />class Suit : public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"西裝 ";<br />}</p><p>};</p><p>//領帶<br />class Tie : public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"領帶 ";<br />}</p><p>};</p><p>//皮鞋<br />class LeatherShoes : public Finery<br />{<br />public:<br />void Show()<br />{<br />cout<<"皮鞋 ";<br />}</p><p>};<br />用戶端<br />// 裝飾模式.cpp : 定義控制台應用程式的進入點。<br />#include <iostream><br />#include "stdafx.h"<br />#include "person.h"<br />#include "Finery.h"<br />//TShirts BigTrouser Sneakers Suit Tie 皮鞋<br />int _tmain(int argc, _TCHAR* argv[])<br />{<br />Person* xc = new Person("小菜");<br />cout<<"第一種裝扮:";</p><p>Finery * ts = new TShirts();<br />Finery * bt = new BigTrouser();</p><p>ts->Show();<br />bt->Show();<br />xc->Show();</p><p>cout<<endl;<br />cout<<"第二種裝扮:";</p><p>Finery * sk = new Sneakers();<br />Finery * st = new Suit();</p><p>sk->Show();<br />st->Show();<br />xc->Show();</p><p>cin.get();<br />return 0;<br />}
服飾類與人類分離了,如果添加“超人”裝扮則只需要添加類就可以了,但是在用戶端需要一條一條地顯示,我們應該在內部組裝完畢,然後再顯示出來。
建造者模式:建造過程必須是穩定的,而現在我們的例子,建造過程是不穩定的,也就是說,通過服飾組合出一個有個性的人完全可以有無數種方案,並非固定的
V1.3 主要是服飾類改變
服飾類<br />class Finery : public Person<br />{<br />protected:<br />Person* component;<br />public:<br />void Decorate(Person* component)<br />{<br />this->component = component;<br />}<br />public:<br />void Show()<br />{<br />if(component != NULL)<br />{<br />component->Show();<br />}<br />}<br />};<br />用戶端<br />#include <iostream><br />#include "stdafx.h"<br />#include "person.h"<br />#include "Finery.h"<br />//TShirts BigTrouser Sneakers Suit Tie 皮鞋<br />int _tmain(int argc, _TCHAR* argv[])<br />{<br />Person* xc = new Person("小菜");<br />cout<<"第一種裝扮:";</p><p>TShirts * ts = new TShirts();<br />BigTrouser * bt = new BigTrouser();</p><p>ts->Decorate(xc);<br />bt->Decorate(ts);<br />bt->Show();</p><p>cout<<endl;<br />cout<<"第二種裝扮:";</p><p>Sneakers * sk = new Sneakers();<br />Suit * st = new Suit();</p><p>sk->Decorate(xc);<br />st->Decorate(sk);<br />st->Show();</p><p>cin.get();<br />return 0;<br />}<br />