大話設計模式:工廠模式
阿新 • • 發佈:2019-01-08
有了前面介紹的簡單工廠模式,為什麼又會出來一個工廠模式呢?它們之間的區別又在哪裡?工廠模式的精髓又在哪裡?
工廠方法模式: 定義一個用於建立物件的介面,主要解決了讓子類決定例項化哪一個類,而不是像簡單工廠一樣,讓工廠來直接決定例項化哪一個產品。工廠方法模式是對簡單工廠模式的稍微改進。工廠方法模式的用意是定義一個建立產品物件的工廠介面,將實際工作推遲到子類中。
還以書上的計算器為例:
工廠模式主要包括以下幾個模組:
(1)抽象工廠:一個介面,子類的具體工廠實現該介面(AbstructFectory);
(2)具體工廠:具體工廠負責生產具體的產品(AddFactory);
(3)抽象產品:具體產品繼承該抽象產品;(Operation);
(4)具體產品:生產具體產品,實際的功能操作(OperationAdd);
優點:使程式模組化更高,低耦合。可維護性更強。
(1)與簡單工廠模式相比,製造產品的工廠類不再只有一個,而是每種具體產品類都對應一個生產它的具體工廠類(OperationAdd--AddFactory)。而這些具體工廠類的共同特徵再被提取出來形成一個抽象產品類(Operation),這些具體產品類都繼承自這個抽象產品類。
(2)當需要增加一種產品的時候,需要做的是:
a.增加一種繼承自抽象產品的具體產品類(開根號的運算類OperationSquart);
b.增加一種繼承在抽象工廠的具體工廠類(SquartFactory),
c.更改客戶端。而不需要在簡單工廠模式中那樣更改工廠類的switch。
因為當我們在要新增一個M的N次方的功能的時候,我們只需要新增一個相應的工廠類和一個相應的運算類就可以了,我們不需要再去修改原有的工廠類了。這樣在新增功能的過程中,整個工廠和產品體系沒有修改的變化,而只是有了擴充套件的變化,這樣就不會影響原有的功能的執行,這樣就符合了另一個非常重要的開放-封閉(對於擴充套件是開放的,對於修改使關閉的)原則精神。
缺點:
(1)只能生產同一種類型的產品,產品結構單一,所有的具體產品都繼承產品抽象類;
(2)簡單工廠模式裡我們是通過修改工廠類你的switch-case來選擇例項化那個物件,但是這裡我們雖然不需要修改工廠類了,但是我們需要修改客戶端,也就是說工廠方法將內部的邏輯判斷移動到了客戶端。本來是要修改工廠類的,但是現在改成了修改客戶端。
其uml圖如下:
工廠方法模式: 定義一個用於建立物件的介面,主要解決了讓子類決定例項化哪一個類,而不是像簡單工廠一樣,讓工廠來直接決定例項化哪一個產品。工廠方法模式是對簡單工廠模式的稍微改進。工廠方法模式的用意是定義一個建立產品物件的工廠介面,將實際工作推遲到子類中。
還以書上的計算器為例:
工廠模式主要包括以下幾個模組:
(1)抽象工廠:一個介面,子類的具體工廠實現該介面(AbstructFectory);
(2)具體工廠:具體工廠負責生產具體的產品(AddFactory);
(3)抽象產品:具體產品繼承該抽象產品;(Operation);
(4)具體產品:生產具體產品,實際的功能操作(OperationAdd);
優點:使程式模組化更高,低耦合。可維護性更強。
(1)與簡單工廠模式相比,製造產品的工廠類不再只有一個,而是每種具體產品類都對應一個生產它的具體工廠類(OperationAdd--AddFactory)。而這些具體工廠類的共同特徵再被提取出來形成一個抽象產品類(Operation),這些具體產品類都繼承自這個抽象產品類。
(2)當需要增加一種產品的時候,需要做的是:
a.增加一種繼承自抽象產品的具體產品類(開根號的運算類OperationSquart);
b.增加一種繼承在抽象工廠的具體工廠類(SquartFactory),
c.更改客戶端。而不需要在簡單工廠模式中那樣更改工廠類的switch。
因為當我們在要新增一個M的N次方的功能的時候,我們只需要新增一個相應的工廠類和一個相應的運算類就可以了,我們不需要再去修改原有的工廠類了。這樣在新增功能的過程中,整個工廠和產品體系沒有修改的變化,而只是有了擴充套件的變化,這樣就不會影響原有的功能的執行,這樣就符合了另一個非常重要的開放-封閉(對於擴充套件是開放的,對於修改使關閉的)原則精神。
缺點:
(1)只能生產同一種類型的產品,產品結構單一,所有的具體產品都繼承產品抽象類;
(2)簡單工廠模式裡我們是通過修改工廠類你的switch-case來選擇例項化那個物件,但是這裡我們雖然不需要修改工廠類了,但是我們需要修改客戶端,也就是說工廠方法將內部的邏輯判斷移動到了客戶端。本來是要修改工廠類的,但是現在改成了修改客戶端。
其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 AbstractFactory { public: virtual Operation* createOperation() { return new Operation; } }; //下面是四個具體工廠類,分別用於產生四個具體產品 class AddFactory:public AbstractFactory { public: Operation* createOperation() { Operation* oper=new OperationAdd; return oper; } }; class SubFactory:public AbstractFactory { public: Operation* createOperation() { Operation* oper=new OperationSub; return oper; } }; class MulFactory:public AbstractFactory { public: Operation* createOperation() { Operation* oper=new OperationMul; return oper; } }; class DivFactory:public AbstractFactory { public: Operation* createOperation() { Operation* oper=new OperationDiv; return oper; } }; //客戶端 int main() { //客戶端判斷具體例項化那個子工廠,那個具體產品; AbstractFactory* af=NULL; af=new AddFactory(); Operation* oper=NULL; oper=af->createOperation(); oper->setA(3); oper->setB(2); cout<<oper->GetResult()<<endl; if(af!=NULL) { delete af; af=NULL; } if(oper!=NULL) { delete oper; oper=NULL; } system("pause"); return 0; }