C++工廠方法之對(duì)象創(chuàng)建型模式詳解
1.代碼示例
工廠方法模式,簡(jiǎn)稱工廠模式或者多態(tài)工廠模式。與簡(jiǎn)單工廠模式相比,引入了更多的新類(lèi),靈活性更強(qiáng),實(shí)現(xiàn)也更加復(fù)雜。符合開(kāi)閉原則,付出的代價(jià)是需要新增加多個(gè)新的工廠類(lèi)。
如下,M_UndeadFactory
、M_ElementFactory
、M_MechanicFactory
類(lèi)有一個(gè)共同的父類(lèi) M_ParFactory(工廠抽象類(lèi))。
M_ParFactory 類(lèi)中的 createMonster 成員函數(shù)其實(shí)就是個(gè)工廠方法,工廠方法模式的名字也是由此而來(lái)。
#include <iostream> using namespace std; // 怪物父類(lèi) class Monster { public: // 構(gòu)造函數(shù) Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {} virtual ~Monster() {} // 父類(lèi)的析構(gòu)函數(shù)應(yīng)該為虛函數(shù) protected: // 可能被子類(lèi)訪問(wèn)的成員,所以用protected修飾 int m_life; // 生命值 int m_magic; // 魔法值 int m_attack; // 攻擊力 }; // 亡靈類(lèi)怪物 class M_Undead : public Monster { public: // 構(gòu)造函數(shù) M_Undead(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)亡靈類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 元素類(lèi)怪物 class M_Element : public Monster { public: // 構(gòu)造函數(shù) M_Element(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)元素類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 機(jī)械類(lèi)怪物 class M_Mechanic : public Monster { public: // 構(gòu)造函數(shù) M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)機(jī)械類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 所有工廠類(lèi)的父類(lèi) class M_ParFactory { public: virtual Monster* createMonster() = 0; // 具體實(shí)現(xiàn)在子類(lèi)中進(jìn)行 virtual ~M_ParFactory() {} // 父類(lèi)的析構(gòu)函數(shù)應(yīng)該為虛函數(shù) }; // M_Undead怪物類(lèi)型的工廠,生產(chǎn)M_Undead類(lèi)型怪物 class M_UndeadFactory : public M_ParFactory { public: virtual Monster* createMonster() { Monster *ptmp = new M_Undead(300, 50, 80); // 創(chuàng)建亡靈類(lèi)怪物 //這里可以增加一些其他業(yè)務(wù)代碼 return ptmp; } }; // M_Element怪物類(lèi)型的工廠,生產(chǎn)M_Element類(lèi)型怪物 class M_ElementFactory : public M_ParFactory { public: virtual Monster* createMonster() { return new M_Element(200, 80, 100); // 創(chuàng)建元素類(lèi)怪物 } }; // M_Mechanic怪物類(lèi)型的工廠,生產(chǎn)M_Mechanic類(lèi)型怪物 class M_MechanicFactory : public M_ParFactory { public: virtual Monster* createMonster() { return new M_Mechanic(400, 0, 110); // 創(chuàng)建機(jī)械類(lèi)怪物 } }; // 全局函數(shù):用于創(chuàng)建怪物對(duì)象 // 注意:形參的類(lèi)型是工廠父類(lèi)類(lèi)型的指針,返回類(lèi)型是怪物父類(lèi)類(lèi)型的指針 Monster* Gbl_CreateMonster(M_ParFactory* factory) { return factory->createMonster(); // createMonster虛函數(shù)扮演了多態(tài)new的行為,factory指向的具體怪物工廠類(lèi)不同,創(chuàng)建的怪物對(duì)象也不同 } int main() { M_ParFactory* p_ud_fy = new M_UndeadFactory(); // 多態(tài)工廠,注意指針類(lèi)型 Monster* pM1 = Gbl_CreateMonster(p_ud_fy); // 產(chǎn)生了一只亡靈類(lèi)怪物,也是多態(tài),注意返回類(lèi)型 // 當(dāng)然,這里也可以直接寫(xiě)成 Monster *pM1 = p_ud_fy->createMonster(); M_ParFactory* p_elm_fy = new M_ElementFactory(); Monster *pM2 = Gbl_CreateMonster(p_elm_fy); // 產(chǎn)生了一只元素類(lèi)怪物 M_ParFactory* p_mec_fy = new M_MechanicFactory(); Monster* pM3 = Gbl_CreateMonster(p_mec_fy); // 產(chǎn)生了一只機(jī)械類(lèi)怪物 // 釋放工廠 delete p_ud_fy; delete p_elm_fy; delete p_mec_fy; // 釋放怪物 delete pM1; delete pM2; delete pM3; return 0; }
簡(jiǎn)單工廠模式把創(chuàng)建對(duì)象這件事放到了一個(gè)統(tǒng)一的地方來(lái)處理,彈性比較差。而工廠方法模式相當(dāng)于建立了一個(gè)程序?qū)崿F(xiàn)框架,從而讓子類(lèi)來(lái)決定對(duì)象如何創(chuàng)建。
工廠方法模式往往需要?jiǎng)?chuàng)建一個(gè)與產(chǎn)品等級(jí)結(jié)構(gòu)(層次)相同的工廠等級(jí)結(jié)構(gòu),這也增加了新類(lèi)的層次結(jié)構(gòu)和數(shù)目。
如果不想創(chuàng)建太多工廠類(lèi),又想封裝變化,則可以創(chuàng)建怪物工廠子類(lèi)模板。
#include <iostream> using namespace std; // 怪物父類(lèi) class Monster { public: // 構(gòu)造函數(shù) Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {} virtual ~Monster() {} // 父類(lèi)的析構(gòu)函數(shù)應(yīng)該為虛函數(shù) protected: // 可能被子類(lèi)訪問(wèn)的成員,所以用protected修飾 int m_life; // 生命值 int m_magic; // 魔法值 int m_attack; // 攻擊力 }; // 亡靈類(lèi)怪物 class M_Undead : public Monster { public: // 構(gòu)造函數(shù) M_Undead(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)亡靈類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 元素類(lèi)怪物 class M_Element : public Monster { public: // 構(gòu)造函數(shù) M_Element(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)元素類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 機(jī)械類(lèi)怪物 class M_Mechanic : public Monster { public: // 構(gòu)造函數(shù) M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack) { cout << "一個(gè)機(jī)械類(lèi)怪物來(lái)到了這個(gè)世界" << endl; } // 其他代碼略 }; // 所有工廠類(lèi)的父類(lèi) class M_ParFactory { public: virtual Monster* createMonster() = 0; // 具體實(shí)現(xiàn)在子類(lèi)中進(jìn)行 virtual ~M_ParFactory() {} // 父類(lèi)的析構(gòu)函數(shù)應(yīng)該為虛函數(shù) }; template <typename T> class M_ChildFactory :public M_ParFactory { public: virtual Monster* createMonster() { return new T(300, 50, 80); //如果需要不同的值則可以通過(guò)createMonster的形參將值傳遞進(jìn)來(lái) } }; int main() { M_ChildFactory<M_Undead> myFactory; Monster* pM10 = myFactory.createMonster(); // 釋放資源 delete pM10; getchar(); return 0; }
UML 如下:
2.工廠方法模式的定義(實(shí)現(xiàn)意圖)
定義一個(gè)用于創(chuàng)建對(duì)象的接口(M_ParFactory類(lèi)中的createMonster成員函數(shù)),由子類(lèi)(M_UndeadFactory
、M_ElementFactory
、M_MechanicFactory
)決定要實(shí)例化的類(lèi)是哪一個(gè)。該模式使得某個(gè)類(lèi)(M_Undead
、M_Element
、M_Mechanic
)的實(shí)例化延遲到子類(lèi)(M_UndeadFactory
、M_ElementFactory
、M_MechanicFactory
)。
一般可以認(rèn)為,將簡(jiǎn)單工廠模式的代碼經(jīng)過(guò)把工廠類(lèi)進(jìn)行抽象改造成符合開(kāi)閉原則后的代碼,就變成了工廠方法模式的代碼。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)小型工資管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)小型工資管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02C語(yǔ)言rewind與fseek函數(shù)之隨機(jī)讀寫(xiě)文件的用法詳解
這篇文章主要介紹了C語(yǔ)言rewind與fseek函數(shù)之隨機(jī)讀寫(xiě)文件的用法詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09C語(yǔ)言實(shí)現(xiàn)九大排序算法的實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于C語(yǔ)言實(shí)現(xiàn)九大排序算法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01C++中的構(gòu)造函數(shù)與析造函數(shù)詳解
這篇文章主要介紹了C++中的構(gòu)造函數(shù)與析造函數(shù)詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06C語(yǔ)言中6組指針和自增運(yùn)算符結(jié)合方式的運(yùn)算順序問(wèn)題
本文通過(guò)代碼實(shí)現(xiàn)分析了6種組合:* p++,(* p)++,* (p++),++* p,++( * p), * (++p),需要的朋友可以參考下2015-07-07vscode搭建STM32開(kāi)發(fā)環(huán)境的詳細(xì)過(guò)程
這篇文章主要介紹了vscode搭建STM32開(kāi)發(fā)環(huán)境的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05