简单工厂模式(Simple Factory)
簡單工廠模式(Simple Factory)
UML類圖示法
矩形框三層:
- 第一層:類的名稱,若為抽象類,斜體顯示
- 第二層:類的特性,通常是字段和屬性
- 第三層:類的操作,通常是方法或行為
- 符號(hào):'+':public, '-':private,'#':protected
類與類,類與接口之間的關(guān)系
- 繼承:空心三角形+實(shí)線
- 接口:空心三角形+虛線
- 關(guān)聯(lián):實(shí)線箭頭
- 聚合:空心菱形+實(shí)線箭頭
- 合成(組合)關(guān)系:實(shí)心的菱形+實(shí)線箭頭
簡單工廠模式
概念
簡單工廠模式(Simple Factory Pattern):又稱為靜態(tài)工廠方法(Static Factory Method)模式,它屬于類創(chuàng)建型模式。在簡單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類的實(shí)例。簡單工廠模式專門定義一個(gè)類來負(fù)責(zé)創(chuàng)建其他類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有共同的父類。
模式結(jié)構(gòu)
主要用于創(chuàng)建對(duì)象。新添加類時(shí),不會(huì)影響以前的系統(tǒng)代碼。核心思想是用一個(gè)工廠來根據(jù)輸入的條件產(chǎn)生不同的類,然后根據(jù)不同類的 virtual 函數(shù)得到不同的結(jié)果。
| 抽象產(chǎn)品角色(Product) | 是所有具體產(chǎn)品角色的父類,它負(fù)責(zé)描述所有實(shí)例所共有的公共接口。 |
| 具體產(chǎn)品角色(Concrete Product) | 繼承自抽象產(chǎn)品角色,一般為多個(gè),是簡單工廠模式的創(chuàng)建目標(biāo)。工廠類返回的都是該角色的某一具體產(chǎn)品。 |
模式實(shí)例與解析(1)
考慮一個(gè)簡單的應(yīng)用場景,一個(gè)計(jì)算器可以提供多個(gè)不同的運(yùn)算符(如加法、減法、乘法、除法等),這些運(yùn)算符都源自同一個(gè)基類,不過在繼承基類后不同的子類修改了部分屬性從而使得它們可以呈現(xiàn)不同的外觀,如果我們希望在使用這些運(yùn)算符時(shí),不需要?jiǎng)?chuàng)建這些子類,只需要知道我要做的是加法還是減法,并把符號(hào)傳入方法即可返回一個(gè)結(jié)果,此時(shí),就可以使用簡單工廠模式。
注:所有用例只為體現(xiàn)設(shè)計(jì)模式思想,不考慮邊界情況,如不考慮除數(shù)為0異常等。
#include <iostream>using namespace std;class Operation{ public:virtual double GetResult() = 0;double GetNumA() { return _numA; }double GetNumB() { return _numB; }void SetNum(double a, double b){_numA = a;_numB = b;}virtual ~Operation() = default; private:double _numA = 0;double _numB = 0; };class OperationAdd : public Operation { public:virtual double GetResult(){double res = 0;res = GetNumA() + GetNumB();return res;} };class OperationSub : public Operation { public:virtual double GetResult(){double res = 0;res = GetNumA() - GetNumB();return res;} };class OperationMul : public Operation { public:virtual double GetResult(){double res = 0;res = GetNumA() * GetNumB();return res;} };class OperationDiv : public Operation { public:virtual double GetResult(){double res = 0;res = GetNumA() / GetNumB();return res;} };class CalculatorFactory { public:static Operation* Create(char c){Operation *oper;switch(c){case '+':oper = new OperationAdd();break;case '-':oper = new OperationSub();break;case '*':oper = new OperationMul();break;case '/':oper = new OperationDiv();break;default:oper = new OperationAdd();break;}return oper;} };int main() {int a, b;cin >> a >> b;Operation * op = CalculatorFactory::Create('+');op->SetNum(a, b);double result = op->GetResult();cout << "result = " << result << endl; }從此以后,如果要加入新的運(yùn)算符,只需要在新增子類并且在工廠類中的添加相應(yīng)符號(hào)。
模式實(shí)例與解析(2)
再考慮一個(gè)簡單的應(yīng)用場景,某商店定期有促銷活動(dòng),有滿300返100,打八折,打五折,滿200返50,等等,這些優(yōu)惠都源自同一個(gè)基類,這也可以用工廠模式。
#include <iostream> #include <string> #include <unordered_map>using namespace std;unordered_map<string, int> mp{{"正常收費(fèi)", 0}, {"滿300返100", 1}, {"打八折", 2}};class CashSuper { public:virtual double accpetCash(double money) = 0; };class CashNormal : public CashSuper { public:virtual double accpetCash(double money){ return money; } };class CashRebate : public CashSuper { public:CashRebate(double moneyRebate):_moneyRebate(moneyRebate){}virtual double accpetCash(double money) { return money * _moneyRebate; } private:double _moneyRebate = 0.9; };class CashReturn : public CashSuper { public:CashReturn(double moneyCondition, double moneyReturn):_moneyCondition(moneyCondition), _moneyReturn(moneyReturn){}double accpetCash(double money){double result = money;if(money >= _moneyCondition){result = money - (money / _moneyCondition) * _moneyReturn; }return result;} private:double _moneyCondition = 0.0;double _moneyReturn = 0.0; };class CashFactory { public:static CashSuper* createCashAccept(string type){int StringValue = mp[type];CashSuper * cs = nullptr;switch(StringValue){case 0:cs = new CashNormal();break;case 1:cs = new CashReturn(300, 100);break;case 2:cs = new CashRebate(0.8);break;}return cs;} };int main() {double total = 0.0;string super;cin >> super;CashSuper *p = CashFactory::createCashAccept(super);total = p->accpetCash(300);cout << "total = " << total << endl;return 0; }因?yàn)镃++中switch(expression)中的expression不支持string類表達(dá)式,所以為實(shí)現(xiàn)功能這里額外調(diào)用了unordered_map來匹配字符串。
工廠類中的方法必須是static方法,于是可以通過類名訪問,也可以通過類的實(shí)例訪問。而普通方法又叫實(shí)例方法,只能通過類的實(shí)例訪問。當(dāng)你需要什么,只需要傳入一個(gè)正確的參數(shù),就可以獲取你所要的的對(duì)象,而無需知道其創(chuàng)建的細(xì)節(jié)。如果不用static反而違背了設(shè)計(jì)模式的初衷!
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):實(shí)現(xiàn)對(duì)象的創(chuàng)建和對(duì)象的使用分離,將對(duì)象的創(chuàng)建交給專門的工廠類負(fù)責(zé)
缺點(diǎn):工廠類不夠靈活,增加新的具體產(chǎn)品需要修改工廠類的判斷邏輯代碼,而且產(chǎn)品較多時(shí),工廠方法代碼將會(huì)非常復(fù)雜。
參考:
《大話設(shè)計(jì)模式》 程杰
http://ruby-java.javaeye.com/blog/169854
轉(zhuǎn)載于:https://www.cnblogs.com/Mered1th/p/10976346.html
總結(jié)
以上是生活随笔為你收集整理的简单工厂模式(Simple Factory)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 5077. 按列翻转得
- 下一篇: 92. Reverse Linked L