首先囉嗦下建立迷宮所用的Room類。這個類並不直接保存Room四周的構造,而是經過MapSite* _sides[4]這個私有數組成員指向Room四周的構造。那麼何時將四周構造直接放在Room中,何時經過指針訪問,這兩種方式各有神馬優缺點?這是個問題[2015.10.07:你沒法預先肯定四周構造的具體類型,因此沒辦法將其直接放在Room中,只能使用基類指針]……不過這不是Abstract Fractory的重點,先放一邊吧。ios
就「Factory」這個詞的本義來講,上面這張圖自己就夠抽象的。讓咱們用更貼近「Factory」一詞的汽車廠來做例子。數組
在遙遠的北方大陸上有兩家汽車廠,一家是BMW,一家是Benz。他們生產的汽車只有兩個部件:方向盤和輪子(別問我這樣的汽車怎麼開)。因而咱們的Abstract Factory有兩個Virtual方法:CreateSteering,CreateWheel。天然,BMWFactory和BenzFactory各自造出的輪子和方向盤是有區別的。ide
另外一方面,無論BMW的輪子仍是Benz的輪子,都是圓的,能在地上滾動的;方向盤一樣有其共同點。因此咱們有AbstractSteering和AbstractWheel以及它們的派生類。函數
綜上,「工廠」有「抽象工廠」和具體的「實際工廠」;spa
「工廠產品」有「抽象產品」和具體的「實際產品」。3d
「工廠類」和其生產產品的「產品類」是分開的,但各個工廠生產的產品種類是同樣的,這樣才能在Factory Class和Product Class之間創建對應關係。指針
下面是代碼:code
1 // 編譯環境:VS2008 2 // AbstractFactory.cpp : 定義控制檯應用程序的入口點。 3 // 4 5 #include "stdafx.h" 6 #include <iostream> 7 8 using namespace std; 9 10 class AbstractWheel 11 { 12 public: 13 14 }; 15 16 class BenzWheel : public AbstractWheel 17 { 18 public: 19 BenzWheel() 20 { 21 cout << "I am BenzWheel" << endl; 22 } 23 }; 24 25 class BMWWheel : public AbstractWheel 26 { 27 public: 28 BMWWheel() 29 { 30 cout << "I am BMWWheel" << endl; 31 } 32 }; 33 34 class AbstractSteering 35 { 36 public: 37 38 }; 39 40 class BenzSteering 41 { 42 public: 43 BenzSteering() 44 { 45 cout << "I am BenzSteering" << endl; 46 } 47 }; 48 49 class BMWSteering 50 { 51 public: 52 BMWSteering() 53 { 54 cout << "I am BMWSteering" << endl; 55 } 56 }; 57 58 class AbstractFactory 59 { 60 public: 61 virtual void CreateWheel(); // No implement in virtual base class 62 virtual void CreateSteering(); // No implement in virtual base class 63 }; 64 65 class BenzFactory 66 { 67 public: 68 virtual void CreateWheel() 69 { 70 new BenzWheel(); 71 } 72 virtual void CreateSteering() 73 { 74 new BenzSteering(); 75 } 76 }; 77 78 class BMWFactory 79 { 80 public: 81 virtual void CreateWheel() 82 { 83 new BMWWheel(); 84 } 85 virtual void CreateSteering() 86 { 87 new BMWSteering(); 88 } 89 }; 90 91 void CreateCar(AbstractFactory& factory) 92 { 93 factory.CreateSteering(); 94 factory.CreateWheel(); 95 } 96 97 int _tmain(int argc, _TCHAR* argv[]) 98 { 99 // I want a BMW car 100 BMWFactory factory; 101 CreateCar((AbstractFactory&)factory); 102 // I want a Benz car 103 //BenzFactory factory; 104 //CreateCar((AbstractFactory&)factory); 105 return 0; 106 }
若是你想要一輛Benz car,將main()中的註釋代碼放開就能夠了。blog
順便說一下,上面代碼中,CreateCar並非Factory類的成員函數;這貌似不符合現實世界汽車廠的一向作法。不過咱們的代碼例子主要爲了演示Abstract Factory模式,而這種模式主要關心的是「產品部件生產」的抽象,而不關心「產品組裝」的抽象,因此代碼和現實的這點區別就忽略吧。或者想想書中不一樣風格窗口的那個例子:不一樣風格窗口的組裝是應用程序的事情,而不是Widget類庫的事情。get