[学习笔记]设计模式之Facade(二)

2014-11-24 01:25:12 · 作者: · 浏览: 3
ateEnchantedWeapon(int, int);
8 // ... other ...
9 }
10
11 EnchantedWeaponFactory::createEnchantedWeapon(int element, int type) {
12 return new EnchantedWeapon(element, type);
13 }
复制代码
暂时还没有建成的护甲工坊:
1 class ArmorFactory : public VisualObject {
2 public:
3 virtual Armor* createArmor() = 0;
4 }
好啦,该去参观参观格琳达的小屋HouseOfGlinda了:
复制代码
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模式简单且易于理解,对于我们来说也很常用。它的优点如下:
它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。Facade模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。Facade模式可以消除复杂的循环依赖关系。这一点在客户程序与子系统是分别实现的时候尤为重要。
如果应用需要,它并不限制它们使用子系统类。因此我们可以在系统易用性和通用性之间加以选择。