爲方便讀者,本文已添加至索引:html
Decorator(裝飾)模式,能夠動態地給一個對象添加一些額外的職能。爲了更好地理解這個模式,咱們將時間線拉回Bridge模式筆記的結尾。那時,白雪公主射出了充滿魔法力量的一箭。如好萊塢大片通常,那支飛出的箭矢散發出各類你能想到的美麗光芒。固然,我不會告訴你那支箭華華麗麗地射偏了。由於咱們此次更關心這絢爛的魔法效果。要說的是,時の魔導士在創建這個平行世界的時候,定義了一個全部可見物體的抽象類VisualObject:設計模式
1 class VisualObject { 2 public: 3 virtual void show() = 0; 4 // ... other ... 5 }
只要是出如今這個世界中,並能被世界以外的人們(好比說咱們)看到的物體,都是它的子類。同時,必須實現show()方法。show定義了這個物體呈現給觀衆的樣式。固然咱們能夠看到時の魔導士在建立箭矢時是如何偷懶的:學習
1 class Arrow : public VisualObject { 2 public: 3 virtual void show() { cout << "你想它是什麼樣就是什麼樣。" << endl; } 4 // ... other ... 5 }
固然,這是不可行的。由於確定有人會把Arrow想像成一個巨大的炮彈,甚至一頭會飛的豬,以此來加強整個故事的動畫性。但不管如何,當魔導士想要告訴你們,公主射出的箭矢是附着着冰霜效果的話,他必須明確地描述這支箭矢到底長什麼樣。若是偷懶到底,他大能夠就創造個Arrow的子類IceArrow,只需多加個關於冰晶的描述就行了。動畫
可是問題來了,既然能夠附着魔法,箭矢就能夠有更多更多的效果:附着火焰的,附着閃電的,長得更好看的,等等等等……若是每個都用子類的話,必然會致使子類數目太多。何況,咱們僅僅是但願給某個對象而不是整個類添加一些特效。同時別忘了咱們還要考慮箭矢以外的能夠附魔的東西。怎麼辦纔好?時の魔導士採用了Decorator模式。spa
請不要太在乎上面這幅圖究竟是誰。爲了能給箭矢(乃至更多物體)增長魔法效果,魔導士引入了ObjectDecorator類:設計
1 class ObjectDecorator : public VisualObject { 2 public: 3 ObjectDecorator(VisualObject *); 4 5 virtual void show(); 6 // ... other ... 7 private: 8 VisualObject* _component; 9 } 10 11 void ObjectDecorator::show() { 12 _component->show(); 13 }
ObjectDecorator裝飾由_component實例變量引用的VisualObject,這個變量在構造器中被初始化。同時,ObjectDecorator將show的請求轉發給_component。咱們將看到ObjectDecorator的子類之一MagicDecorator,它將能給可視化物件添加魔法的神奇效果:指針
1 class MagicDecorator : public ObjectDecorator { 2 public: 3 MagicDecorator(VisualObject *, int); 4 virtual void show(); 5 // ... other ... 6 private: 7 int _magicType; 8 9 void addMagic(int); 10 } 11 12 void MagicDecorator::show() { 13 ObjectDecorator::show(); 14 addMagic(_magicType); 15 }
相似的,咱們也能夠實現別的裝飾類。咱們接下來要把這個箭矢放到這個世界中去。假設World類(一個單例類)已經爲此提供了一個add2Me操做:code
1 void World::add2Me(VisualObject* obj) { 2 // ... 3 obj->show(); 4 // ... 5 }
如今咱們要讓身處世界以外的人也看到一根箭矢,只需這麼作:component
1 Arrow* arrow = new Arrow(); 2 World::getInstance()->add2Me(arrow);
那麼此刻,正是展示電影特效各類神奇絢麗效果的時刻了。咱們在將箭矢放入世界以前,先給它加上一層寒冰魔法的裝飾:htm
1 #define ICEMAGIC 1 2 World::getInstance()->add2Me(new MagicDecorator(arrow, ICEMAGIC));
OK,白雪公主射出了一支帶有寒冰魔法的箭矢。下面的UML圖說明了咱們這個例子:
能夠看到Decorator裝飾模式有如下2個主要優勢和缺點:
一樣,咱們在使用這個方法時,也要注意:
今天的筆記就到這裏了,歡迎你們批評指正!若是以爲能夠的話,好文推薦一下,我會很是感謝的!