爲方便讀者,本文已添加至索引:html
Facade(外觀)模式定義了一個高層接口,它能爲子系統中的一組接口提供一個一致的界面,從而使得這一子系統更加容易使用。歡迎回到時の魔導士的魔法世界。在對戰壞女巫的魔法生物一役中(見Bridge模式筆記),白雪公主得到大逆轉勝利機會的關鍵是附魔武器的誕生。可是,普通的武器工坊(見FactoryMethod模式筆記)生產不了附魔武器,只能是經過特殊的附魔工坊得到。通過這一戰以後,你們也以爲除了武器,還須要能保護身體的護甲來抵擋傷害。所以,霍比特人們又打算創建一些護甲工坊。如此一來,用於生產戰鬥用品的系統就愈來愈多了。小霍比特人們若是須要得到一整套適合本身的戰鬥用品,就不得不分別調用每一個系統的生產方法。事實上,小霍比特人們並不關心每一個系統具體的工做細節,他們只想要獲得一件成品而已。對於他們而言,這些生產系統中那些功能強大但層次較低的接口只會使他們的任務複雜化。設計模式
爲了讓小霍比特人們的生活、戰鬥更便利,好女巫格琳達(Glinda原型請參見《魔境仙蹤》,固然,你不會忘記一點:我確定不會忠於原著)爲他們提供了一個高層接口,而且對他們屏蔽了這些生產系統類——格琳達的小屋,在森林裏面正式開業了。因而小霍比特人們只須要來到小屋中,告訴Glinda本身須要什麼,再付上一點點小酬勞,就能夠獲得想到的東西啦。架構
那這一切跟咱們今天筆記的主題有什麼關係呢?其實這正是Facade模式一個例子,咱們將在示例分析部分更加詳細地探討這個問題。首先仍是讓咱們快速地熟悉下什麼是Facade模式吧!ide
在咱們前來參觀格琳達的小屋以前,不妨先回顧一下那些生產戰鬥用品的子系統,從而能更好地理解Facade模式工做的機制。因爲在Bridge模式筆記中提到Weapon類的設計架構發生了改變,所以包括普通的武器工坊在內的設計也相應地進行了調整。學習
首先是咱們基本的Weapon類:spa
1 class Weapon : public VisualObject { 2 public: 3 Weapon(int); 4 ~Weapon() { delete _impl; } 5 // ... other ... 6 protected: 7 WeaponImpl* getWeaponImpl(); 8 private: 9 WeaponImpl* _impl; 10 } 11 12 Weapon::Weapon(int type) { 13 switch(type) 14 { 15 case WEAPON_SWORD: 16 _impl = new SwordImpl(); 17 break; 18 case WEAPON_SHIELD: 19 _impl = new ShieldImpl(); 20 break; 21 case WEAPON_BOW: 22 _impl = new BowImpl(); 23 break; 24 // ... other cases ... 25 default: 26 break; 27 } 28 }
還有調整後的WeaponFactory類以及它的子類們:設計
1 class WeaponFactory { 2 public: 3 virtual Weapon* createWeapon() = 0; 4 } 5 6 class HonorOfFighter : public WeaponFactory { 7 public: 8 HonorOfFighter(); 9 Weapon* createWeapon() { return new Weapon(WEAPON_SWORD); } 10 } 11 12 class BliefOfDefender : public WeaponFactory { 13 public: 14 BliefOfDefender(); 15 Weapon* createWeapon() { return new Weapon(WEAPON_SHEILD); } 16 } 17 18 class PrecisionOfHunter : public WeaponFactory { 19 public: 20 PrecisionOfHunter(); 21 Weapon* createWeapon() { return new Weapon(WEAPON_BOW); } 22 } 23 24 // ... other weapon factories ...
以及前文中提到的附魔工坊:代理
1 #define ENCHANTED_ICE 1 2 #define ENCHANTED_FIRE 2 3 #define ENCHANTED_SHOCK 3 4 5 class EnchantedWeaponFactory { 6 public: 7 Weapon* createEnchantedWeapon(int, int); 8 // ... other ... 9 } 10 11 EnchantedWeaponFactory::createEnchantedWeapon(int element, int type) { 12 return new EnchantedWeapon(element, type); 13 }
暫時尚未建成的護甲工坊:code
1 class ArmorFactory : public VisualObject { 2 public: 3 virtual Armor* createArmor() = 0; 4 }
好啦,該去參觀參觀格琳達的小屋HouseOfGlinda了:htm
1 #define NOTHING 0 2 3 class HouseOfGlinda { 4 public: 5 VisualObject* onSale(int, int); // a simple interface. 6 7 // ... It's a Singleton ... 8 static HouseOfGlinda* getInstance() { 9 if (_instance == 0) { 10 _instance = new HouseOfGlinda(); 11 } 12 13 return _instance; 14 } 15 16 protected: 17 Weapon* getWeapon(int); 18 Weapon* getEnchantedWeapon(int, int); 19 // ... Armor will be comming soon ... 20 private: 21 HouseOfGlinda(); 22 static HouseOfGlinda* _instance; 23 } 24 25 VisualObject* HouseOfGlinda::onSale(int type, int info) { 26 if (WEAPON_SWORD == type || 27 WEAPON_SHIELD == type || 28 WEAPON_BOW == type 29 // ... other weapon ... 30 ) { 31 32 if (NOTHING == info) { 33 return getWeapon(type); 34 } 35 else { 36 return getEnchantedWeapon(type, info); 37 } 38 } 39 // else for armor ... 40 } 41 42 Weapon* HouseOfGlinda::getWeapon(int type) { 43 WeaponFacotry* factory = 0; 44 Weapon* weapon = 0; 45 switch(type) { 46 case WEAPON_SWORD: 47 factory = new HonorOfFighter(); 48 break; 49 case WEAPON_SHIELD: 50 factory = new BliefOfDefender(); 51 break; 52 // ... other cases ... 53 default: 54 break; 55 } 56 weapon = factory->createWeapon(); 57 if (factory) delete factory; 58 return weapon; 59 } 60 61 Weapon* HouseOfGlinda::getEnchantedWeapon(int type, int info) { 62 EnchantedWeaponFactory factory; 63 return factory.createEnchantedWeapon(info, type); 64 }
注意到HouseOfGlinda類中,onSale接口對客戶屏蔽了子系統中的組件(譬如說WeaponFactory以及EnchantedWeaponFactory,甚至還在建設當中的ArmorFactory),做爲客戶的小霍比特人們只須要發送請求給HouseOfGlinda對象,它就能將消息轉發給相應的子系統去處理,比方說,有人想要一把普通的劍,而另外一我的想要一面冒着火焰的盾牌:
1 VisualObject* obj1 = HouseOfGlinda::getInstance->onSale(WEAPON_SHIELD, ENCHANTED_FIRE); 2 VisualObject* obj2 = HouseOfGlinda::getInstance->onSale(WEAPON_SWORD, NOTHING);
瞧,多方便呀。此外,若是真有須要,小霍比特人仍是能夠直接訪問工坊從而得到私人定製的武器。固然經過格琳達的小屋會更加方便,這樣他們有更多時間去享受啤酒和美食的樂趣了。
一張簡單的UML圖:
Facade模式簡單且易於理解,對於咱們來講也很經常使用。它的優勢以下:
今天的筆記就到這裏了,歡迎你們批評指正!若是以爲能夠的話,好文推薦一下,我會很是感謝的!