大話設計模式:簡單工廠模式
阿新 • • 發佈:2019-01-03
由於面向過程程式設計造成的程式碼膨脹問題越來越嚴重,使其維護的代價高,靈活性很低。為了使程式碼易維護、易擴充套件、易複用和靈活性好,所以我們在採用面向物件程式設計的時候,防止採用面向物件的語言實際上卻做著面向過程的事兒,更需要採用某種設計模式,核心就是使程式變得高內聚,低耦合,這樣的程式才能達到上面的四個優點。而簡單工廠模式的出現也正是為了達到這樣一種效果,將工廠和產品分塊,具體解決了例項化那個物件(具體產品)的需求。從而實現了高內聚,低耦合。使程式易維護、易擴充套件、易複用和靈活性好。同時也用到了面向物件程式設計的三大特性:繼承、多型、封裝。
簡單工廠模式主要包括以下幾個模組:
(1)工廠類Factory:在Factory中有一個用於製造產品的Create函式,用於製造產品。裡面有個switch-case語句,這個函式能夠根據“識別符號”的不同生成不同的ConcreteProduct,當然這些ConcreteProduct都是繼承自AbstractProduct的。
(2)抽象產品類: AbstructProduct:抽象產品是從其他具體產品抽象出來的。抽象產品類只有一個。
(3)具體產品類ConcreteProduct:具體產品類繼承自抽象產品類,可以有多個。
以書上的計算器為例:
優點:實現了低耦合。當需要增加一種新產品(以新增開根號運算為例),只需要做兩點改動:
(1)增加一個繼承自抽象產品--抽象運算--的具體產品(新增一個開根號的類,繼承Operation類);
(2)在工廠中,switch中,增加一種根據識別符號產生新運算的case即可(新增一個case的變數,開根號);
缺點:只能生產一種型別的產品,該產品都繼承抽象產品類(該書中所指的就是運算類:Operation類,每種具體的運算(+-*/)都需要繼承該類。但是如果後來我們需要播放一首歌曲或者畫出不同圖形這樣的功能,這個簡單工廠模式就不行了,具體實現思想後面再介紹。因為它只能實現某一類抽象的產品,)。
其UML圖如下:
其具體實現程式碼:
簡單工廠模式主要包括以下幾個模組:
(1)工廠類Factory:在Factory中有一個用於製造產品的Create函式,用於製造產品。裡面有個switch-case語句,這個函式能夠根據“識別符號”的不同生成不同的ConcreteProduct,當然這些ConcreteProduct都是繼承自AbstractProduct的。
(2)抽象產品類:
(3)具體產品類ConcreteProduct:具體產品類繼承自抽象產品類,可以有多個。
以書上的計算器為例:
優點:實現了低耦合。當需要增加一種新產品(以新增開根號運算為例),只需要做兩點改動:
(1)增加一個繼承自抽象產品--抽象運算--的具體產品(新增一個開根號的類,繼承Operation類);
(2)在工廠中,switch中,增加一種根據識別符號產生新運算的case即可(新增一個case的變數,開根號);
缺點:只能生產一種型別的產品,該產品都繼承抽象產品類(該書中所指的就是運算類:Operation類,每種具體的運算(+-*/)都需要繼承該類。但是如果後來我們需要播放一首歌曲或者畫出不同圖形這樣的功能,這個簡單工廠模式就不行了,具體實現思想後面再介紹。因為它只能實現某一類抽象的產品,)。
其UML圖如下:
其具體實現程式碼:
#include <iostream> using namespace std; //抽象產品類 class Operation { protected: double numberA; double numberB; public: double getA() { return numberA; } double getB() { return numberB; } void setA(double number) { numberA=number; } void setB(double number) { numberB=number; } virtual double GetResult() { double result=0; return result; } }; //下面是四種具體產品類,只能是同一類的產品; class OperationAdd:public Operation { public: double GetResult() { double result=0; result=numberA+numberB; return result; } }; class OperationSub:public Operation { public: double GetResult() { double result=0; result=numberA-numberB; return result; } }; class OperationMul:public Operation { public: double GetResult() { double result=0; result=numberA*numberB; return result; } }; class OperationDiv:public Operation { public: double GetResult() { double result=0; if(numberB!=0) result=numberA/numberB; return result; } }; //工廠類,決定例項化那個產品; class OperationFactory { public: Operation* createOperation(char type) { Operation* oper; switch(type) { case '+': oper=new OperationAdd; break; case '-': oper=new OperationSub; break; case '*': oper=new OperationMul; break; case '/': oper=new OperationDiv; break; } return oper; } }; //客戶端 int main() { Operation* oper=NULL; OperationFactory of; oper=of.createOperation('+'); oper->setA(3); oper->setB(2); cout<<oper->GetResult()<<endl; if(oper!=NULL) { delete oper; oper=NULL; } system("pause"); return 0; }
執行結果: