對象工廠,顧名思義,就是產生對象的一個“工廠”。根據傳入的一個參數而產生相應的不同種類的對象。
用於批量生成同一個父類的不同子類的對象時用到。
本學習筆記基於Singleton(單件模式)基礎上進行擴展。
看《C++單件模式:Singleton學習筆記》請點擊鏈接。
對於工廠模式,網上有很多不同的實現方法。我這裏是一個HGE的RPG Demo中所用的,這段代碼本身寫的非常的好,開始好些語句沒看懂,雖然就這麼幾句話。花了一點時間去研究了其代碼,並自己重新實現了一遍,加上了通俗易懂的註釋。
工廠類以模板形式實現,基於Singleton:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| * 對象工廠模式(Object Factory) * * Code by XadillaX * http://www.xcoder.in * Created at 2010-11-17 1:33 */ #ifndef OBJECTFACTORY_H #define OBJECTFACTORY_H #pragma once #include #include #include "../單件模式/Singleton.h"
template<class T> class ObjectFactory : public Singleton> { public: typedef T* (*tCreator)(); typedef std::map<std::string, tCreator> tCreatorMap;
* @brief 註冊新“生產車間” * 將生成對象的函數加入對象工廠 * * @param *name 類名稱 * @param procedure “生產”對象的函數 * @return 是否成功註冊 */ bool Register(char *type, tCreator procedure);
* @brief 找到“生產車間” * 根據傳入的類名返回相應的新對象的生成函數 * * @param &type; 類名 * @return 相應的新對象的生成函數 */ T* Create(const std::string &type;);
private: tCreatorMap _map; };
template<class T> bool ObjectFactory::Register(char *type, tCreator procedure) { string tmp(type); _map[tmp] = procedure; return _map[tmp]; }
template<class T> T* ObjectFactory::Create(const std::string &type;) { tCreatorMap::iterator iter = _map.find(type);
if(iter != _map.end()) { tCreator r = iter->second;
return r(); }
return 0; }
#endif
|
以上就是基於單件模式而實現的工廠模式了。
在樣例中,我建立了一個基類Base,然後用A和B來繼承它。
在一個for循環中,交替建立了A對象和B對象。這只是一個Demo,看不出有什麼方便的,感覺用一個if來各自生成就好了,就像
1 2
| if(type == "A") p = new A(); else p = new B();
|
當然,上面也是一種方法。但是,試想一下,我們將要創建的A、B、C、D、E、F、G類放到一個配置文件中,然後我們從配置文件中讀取這些數據並創建相應的對象,並且這些對象的順序是打亂的,你就要有n個if來判斷了,而且擴展性不高。用一個對象工廠進行封裝的話,儼然形成了一個靜而有序的生產工廠,有秩序地管理着不同的對象車間,不覺得這是一件非常美妙的事情麼?
好了,話不多說,直接上Demo。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include #include "ObjectFactory.h" using namespace std;
class Base;
typedef ObjectFactory BaseFactory;
class Base { public: Base(){}; ~Base(){}; };
class A : public Base { public: A(){ cout << "An A object created." << endl; }; ~A(){}; };
class B : public Base { public: B(){ cout << "A B object Created." << endl; } ~B(); };
Base* ACreator() { return new A(); }
Base* BCreator() { return new B(); }
* @brief 主函數 */ int main() { bool AFlag = BaseFactory::Instance().Register("A", ACreator); bool BFlag = BaseFactory::Instance().Register("B", BCreator);
if(!AFlag || !BFlag) exit(0);
Base *p; for(int i = 0; i < 10; i++) { string type = (i % 2) ? string("A") : string("B");
p = BaseFactory::Instance().Create(type);
delete p; }
return 0; }
|