C++工廠方法之對象創(chuàng)建型模式詳解
1.代碼示例
工廠方法模式,簡稱工廠模式或者多態(tài)工廠模式。與簡單工廠模式相比,引入了更多的新類,靈活性更強,實現(xiàn)也更加復(fù)雜。符合開閉原則,付出的代價是需要新增加多個新的工廠類。
如下,M_UndeadFactory、M_ElementFactory、M_MechanicFactory 類有一個共同的父類 M_ParFactory(工廠抽象類)。
M_ParFactory 類中的 createMonster 成員函數(shù)其實就是個工廠方法,工廠方法模式的名字也是由此而來。
#include <iostream>
using namespace std;
// 怪物父類
class Monster
{
public:
// 構(gòu)造函數(shù)
Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
virtual ~Monster() {} // 父類的析構(gòu)函數(shù)應(yīng)該為虛函數(shù)
protected: // 可能被子類訪問的成員,所以用protected修飾
int m_life; // 生命值
int m_magic; // 魔法值
int m_attack; // 攻擊力
};
// 亡靈類怪物
class M_Undead : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個亡靈類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 元素類怪物
class M_Element : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個元素類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 機械類怪物
class M_Mechanic : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個機械類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 所有工廠類的父類
class M_ParFactory
{
public:
virtual Monster* createMonster() = 0; // 具體實現(xiàn)在子類中進(jìn)行
virtual ~M_ParFactory() {} // 父類的析構(gòu)函數(shù)應(yīng)該為虛函數(shù)
};
// M_Undead怪物類型的工廠,生產(chǎn)M_Undead類型怪物
class M_UndeadFactory : public M_ParFactory
{
public:
virtual Monster* createMonster()
{
Monster *ptmp = new M_Undead(300, 50, 80); // 創(chuàng)建亡靈類怪物
//這里可以增加一些其他業(yè)務(wù)代碼
return ptmp;
}
};
// M_Element怪物類型的工廠,生產(chǎn)M_Element類型怪物
class M_ElementFactory : public M_ParFactory
{
public:
virtual Monster* createMonster()
{
return new M_Element(200, 80, 100); // 創(chuàng)建元素類怪物
}
};
// M_Mechanic怪物類型的工廠,生產(chǎn)M_Mechanic類型怪物
class M_MechanicFactory : public M_ParFactory
{
public:
virtual Monster* createMonster()
{
return new M_Mechanic(400, 0, 110); // 創(chuàng)建機械類怪物
}
};
// 全局函數(shù):用于創(chuàng)建怪物對象
// 注意:形參的類型是工廠父類類型的指針,返回類型是怪物父類類型的指針
Monster* Gbl_CreateMonster(M_ParFactory* factory)
{
return factory->createMonster();
// createMonster虛函數(shù)扮演了多態(tài)new的行為,factory指向的具體怪物工廠類不同,創(chuàng)建的怪物對象也不同
}
int main()
{
M_ParFactory* p_ud_fy = new M_UndeadFactory(); // 多態(tài)工廠,注意指針類型
Monster* pM1 = Gbl_CreateMonster(p_ud_fy); // 產(chǎn)生了一只亡靈類怪物,也是多態(tài),注意返回類型
// 當(dāng)然,這里也可以直接寫成 Monster *pM1 = p_ud_fy->createMonster();
M_ParFactory* p_elm_fy = new M_ElementFactory();
Monster *pM2 = Gbl_CreateMonster(p_elm_fy); // 產(chǎn)生了一只元素類怪物
M_ParFactory* p_mec_fy = new M_MechanicFactory();
Monster* pM3 = Gbl_CreateMonster(p_mec_fy); // 產(chǎn)生了一只機械類怪物
// 釋放工廠
delete p_ud_fy;
delete p_elm_fy;
delete p_mec_fy;
// 釋放怪物
delete pM1;
delete pM2;
delete pM3;
return 0;
}
簡單工廠模式把創(chuàng)建對象這件事放到了一個統(tǒng)一的地方來處理,彈性比較差。而工廠方法模式相當(dāng)于建立了一個程序?qū)崿F(xiàn)框架,從而讓子類來決定對象如何創(chuàng)建。
工廠方法模式往往需要創(chuàng)建一個與產(chǎn)品等級結(jié)構(gòu)(層次)相同的工廠等級結(jié)構(gòu),這也增加了新類的層次結(jié)構(gòu)和數(shù)目。
如果不想創(chuàng)建太多工廠類,又想封裝變化,則可以創(chuàng)建怪物工廠子類模板。
#include <iostream>
using namespace std;
// 怪物父類
class Monster
{
public:
// 構(gòu)造函數(shù)
Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
virtual ~Monster() {} // 父類的析構(gòu)函數(shù)應(yīng)該為虛函數(shù)
protected: // 可能被子類訪問的成員,所以用protected修飾
int m_life; // 生命值
int m_magic; // 魔法值
int m_attack; // 攻擊力
};
// 亡靈類怪物
class M_Undead : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個亡靈類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 元素類怪物
class M_Element : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個元素類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 機械類怪物
class M_Mechanic : public Monster
{
public:
// 構(gòu)造函數(shù)
M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
{
cout << "一個機械類怪物來到了這個世界" << endl;
}
// 其他代碼略
};
// 所有工廠類的父類
class M_ParFactory
{
public:
virtual Monster* createMonster() = 0; // 具體實現(xiàn)在子類中進(jìn)行
virtual ~M_ParFactory() {} // 父類的析構(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); //如果需要不同的值則可以通過createMonster的形參將值傳遞進(jìn)來
}
};
int main()
{
M_ChildFactory<M_Undead> myFactory;
Monster* pM10 = myFactory.createMonster();
// 釋放資源
delete pM10;
getchar();
return 0;
}
UML 如下:

2.工廠方法模式的定義(實現(xiàn)意圖)
定義一個用于創(chuàng)建對象的接口(M_ParFactory類中的createMonster成員函數(shù)),由子類(M_UndeadFactory、M_ElementFactory、M_MechanicFactory)決定要實例化的類是哪一個。該模式使得某個類(M_Undead、M_Element、M_Mechanic)的實例化延遲到子類(M_UndeadFactory、M_ElementFactory、M_MechanicFactory)。
一般可以認(rèn)為,將簡單工廠模式的代碼經(jīng)過把工廠類進(jìn)行抽象改造成符合開閉原則后的代碼,就變成了工廠方法模式的代碼。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C語言rewind與fseek函數(shù)之隨機讀寫文件的用法詳解
這篇文章主要介紹了C語言rewind與fseek函數(shù)之隨機讀寫文件的用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09
C++中的構(gòu)造函數(shù)與析造函數(shù)詳解
這篇文章主要介紹了C++中的構(gòu)造函數(shù)與析造函數(shù)詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
C語言中6組指針和自增運算符結(jié)合方式的運算順序問題
本文通過代碼實現(xiàn)分析了6種組合:* p++,(* p)++,* (p++),++* p,++( * p), * (++p),需要的朋友可以參考下2015-07-07
vscode搭建STM32開發(fā)環(huán)境的詳細(xì)過程
這篇文章主要介紹了vscode搭建STM32開發(fā)環(huán)境的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05

