設計乙個簡單的計算器,能夠完成加減乘除的操作,並且能夠設定運算的兩個運算元(暫時不考慮計算器的介面)。
可以建立乙個計算器類,裡面包含加減乘除的運算,以及設定獲取運算元等操作,客戶端直接建立乙個計算器的物件,呼叫對應介面去執行運算。如果後續要新增新的運算,每次需要更改計算器類。
風險:由於新增操作每次要更改原來設計的類,可能會由於不小心改掉了原來的實現計算邏輯,從而導致原來正常執行的程式得不到正確的結果。
為每種運算單獨設計乙個類,客戶端使用的時候可以根據不同的運算建立不同的物件,執行相應的操作。
由於每種運算子都有類似的操作,只是最終對資料執行的運算不一樣,為了避免每個運算類寫重複的**,可以抽象出來乙個運算類,包含公共的方法(設定運算元,獲取運算元,獲取計算結果等),具體運算類應該繼承這個基類,在每個子類分別執行自己的運算。
此時,客戶端需要使用運算器的時候,建立物件使用new的時候還是需要知道每個運算類的類名,若這些類分別在不同的標頭檔案宣告,使用這些類的時候還需要include一堆的標頭檔案。如果要新增加運算子,上述的地方都要改動,很容易遺漏,非常的繁瑣。
解決方案:由於建立的物件都是類似的物件(他們的父類都是同乙個),可以建立乙個類,提供乙個靜態方法,把建立具體類物件的工作都放到這個類中來完成,當客戶端需要使用運算器的時候,就只需跟這個建立類打交道,並且使用這些物件的時候直接通過運算類的基類引用或者指標來執行操作就行了。當然,客戶端和建立類需要使用一些通用的約定方式來表示要建立哪種型別的運算例項。針對本需求,可以直接使用加減乘數的字元來進行約定(「+」,「-」,「*」,「/」)。通過這個修改之後,就能夠降低客戶與每種運算類的耦合度。如果後續需要增加新的運算類,也不需要更改原來已經實現完好的各個具體的運算類,也就不會導致原來正常執行的結果由於不小心修改了原有**導致結果不正確。
而上述所說的為了建立具體運算物件和增加的類,就是乙個工廠類,解決方案就是簡單工廠模式。
簡單工廠模式並不屬於23種gof設計模式之一。
簡單工廠模式違背了物件導向設計中的開放封閉原則(簡而言之,就是對擴充套件開放,對修改封閉)。按照上述的需求,需要增加一種運算,不妨就假設增加指數運算。此時需要增加乙個指數運算類(這種是擴充套件操作,不修改原有實現,只要新增乙個類,就是對擴充套件開放),還需要在工廠類中增加一種物件的建立邏輯(這種是修改操作,物件導向不提倡修改,就是對修改封閉),這樣的修改還是會導致風險。
標頭檔案calculator.h,宣告了抽象類運算類,以及具體的運算類,還有運算器工廠類
1實現檔案calculator.cpp,生面宣告的每個類的具體實現#ifndef __calculator_h__
2#define __calculator_h__34
//運算抽象類
5class
myoperator
69 virtual ~myoperator() {}
1011
//獲取運算結果
12virtual
double getresult()=0;13
//獲取運算元
14double getnuma()const
15double getnumb()const
16//
獲取運算子
17char getop()const
18//
設定運算元
19void setnuma(double a)
20void setnumb(double b)
2122
private:23
//運算子
24char
m_op;
25//
運算的兩個運算元
26double
m_numbera;
27double
m_numberb;
28};
2930
//加法運算類:繼承運算抽象類
31class operatorplus:public
myoperator
3235
virtual
double
getresult();
36};
3738
//減法運算類:繼承運算抽象類
39class operatorminus :public
myoperator
4043
virtual
double
getresult();
44};
4546
//乘法運算類:繼承運算抽象類
47class operatormultiply :public
myoperator
4851
virtual
double
getresult();
52};
5354
//除法運算類:繼承運算抽象類
55class operatordivision :public
myoperator
5659
virtual
double
getresult();
60};
6162
//運算工廠類,用於生產客戶端需要的具體類
63class
operato***ctory64;
68#endif
1 #include 2 #include "測試檔案testcalculator.cpp,呼叫運算器類的客戶端calculator.h"3
4using
namespace
std;56
//加法運算
7double
operatorplus::getresult()811
12//
減法運算
13double
operatorminus::getresult()
1417
18//
乘法運算
19double
operatormultiply::getresult()
2023
24//
除法運算
25double
operatordivision::getresult()
2632
else
3336
return
result;37}
3839
//運算工廠類,用於生產客戶端需要的具體運算類
40 myoperator* operato***ctory::getoperator(char opstr,double a,double
b)41
56 }
1 #include "執行結果calculator.h
"2 #include 3
4using
namespace
std;56
intmain()729
return0;
30 }
工廠模式 簡單工廠
簡單工廠其實並不是乙個設計模式,反而比較像一種程式設計習慣。我個人的這樣總結簡單工廠 建立乙個類,封裝建立物件的 故事 現在我要開一家披薩店,叫bbk 必敗客 披薩,賣很多種披薩 芝士披薩 榴蓮披薩等等,我有乙個orderpizza string type 方法,根據客戶傳來的type來提供不同的披...
工廠模式 簡單工廠
工廠 處理建立物件的細節。目的 將例項化具體類的 從應用中抽離,或者封裝起來,可以避免干擾應用的其他部分。簡單工廠 簡單工廠其實不是乙個設計模式,反而像一種程式設計習慣。產品實現 desc 產品a public inte ce a class a1 implements a override pub...
簡單工廠模式,工廠模式,抽象工廠模式
三種模式看了一天,記錄下自己的理解 headfirst,比薩店為例 1,簡單工廠模式 乙個具體的工廠類 pizzafactory 乙個抽象的產品類pizza,可以派生出多個具體的產品類 客戶 pizzastore類 工廠類 pizzafactory類關聯產品類pizza,工廠生產出不同型別的pizz...