三種工廠模式詳解


 

我的相關博文:

別只知道策略模式+簡單工廠,試試更香的策略模式+抽象工廠!

 

1. 簡單工廠模式, 一圖就看盡

    涉及: 產品抽象類(即水果類)  、 工廠類、具體產品類(香蕉類、蘋果類)

 

 

 

2.

工廠方法模式使用先來看一下,上截圖:

 

 工廠方法模式的實現:

 3             class SingleCore  // 抽象類,抽象的處理器類。 具體產品的基類 
 4             {
 5             public:
 6                 virtual void Show() = 0;
 7             };
 8             class SingleCoreA:public SingleCore // 具體型號的處理器A 具體的產品類
 9             {
10             public:
11                 void Show()
12                 {
13                     cout << "單核處理器 A型" << endl;
14                 }
15             };
16             class SingleCoreB:public SingleCore // 具體型號的處理器B 具體的產品類
17             {
18             public:
19                 void Show()
20                 {
21                     cout << "單核處理器 B型" << endl;
22                 }
23             };
24             class Factory   // 抽象類, 工廠類  具體工廠的基類
25             {
26             public:
27                 virtual SingleCore* CreateSingleCore() = 0;
28             };
29             class FactoryA:public Factory // 具體的工廠類 廠子1
30             {
31             public:
32                 SingleCore* CreateSingleCore()
33                 {
34                     cout << "Create SingleCore A" << endl;
35                     return new SingleCoreA(); // 廠子1生產A型CPU
36                 }
37             };
38             class FactoryB:public Factory // 具體的工廠類 廠子2
39             {
40             public:
41                 SingleCore* CreateSingleCore()
42                 {
43                     cout << "Create SingleCore B" << endl;
44                     return new SingleCoreB(); //廠子2生產B型CPU
45                 }
46             };

  

小結:

前者是簡單工廠模式、后者是工廠方法模式。 

簡單工廠=》優點:使用簡單。缺點:父類決定實例化哪個類, 在工廠內部直接創建產品,導致新增產品時就需要去修改工廠類的內部代碼。  

工廠方法=》優點:讓子類決定實例化哪個類,將創建過程延遲到子類進行。   缺點:每增加一個新產品,就需要增加一個新產品的工廠。

個人見解:

感悟1.

工廠方法類的核心是一個抽象的工廠類,而簡單工廠模式把核心放在一個具體類上。
工廠方法模式之所以有一個別名叫多態性工廠模式,是因為具體工廠類都有共同的抽象父類。

感悟2.

縱觀本例需要實現的功能:吃蘋果、吃香蕉,吃是動詞。蘋果或香蕉是名詞,

顯然,如果我們能封裝出一個吃函數,其參數是具體水果的標識(或稱為ID,標識具體水果品種),那么用戶使用時候會更加方便。

從本例子來看,簡單工廠模式在使用的時候可以傳入特定字符串,顯然是簡單工廠模式更加容易封裝出符合此要求的函數,而工廠方法模式則不太容易滿足此要求。 

最后,我的態度是設計模式沒有好壞,只有根據當前場景、程序員的需求,進行特定的挑選和使用。

 

 

 3.抽象工廠模式

抽象工廠模式是一個創建型設計模式,它針對的是創建產品族,而不是單單一個產品。

說大白話,上面的工廠方法模式的示例代碼,只維護了一個SingleCore類,也就是只有一個產品線。

如果是維護多個產品線的情況,例如有生產CPU,還有生產水果,還有輸出語音控制(每種語音可視為一種產品,其抽象類則是獲取對應的語音ID)等,

那么抽象的工廠類里就需要聲明多個純虛函數。

經過這樣的簡單修改,就可以創建產品族,這就成了抽象工廠模式了。所以,抽象工廠和工廠方法其實是極其類似的。

#include <iostream>
#include <string>
 
using namespace std;
 
// 點評shape類: 一條產品線下的產品,通常存在共性,也就是說,一個產品抽象類通常是需要的,而不是必須的。   
class Shape
{
public:
    virtual void draw()=0;
    virtual ~Shape(){}
};
 
class Rectangle :public Shape
{
public:
    void draw()
    {
        cout << "from rectangle"<<endl;
    }
};
 
class Circle :public Shape
{
public:
    void draw()
    {
        cout << "from circle"<< endl;
    }
};

// 點評color類: 一條產品線下的產品,通常存在共性,也就是說,一個產品抽象類通常是需要的,而不是必須的。    class Color { public: virtual void fill()=0; virtual ~Color(){} }; class Green:public Color { public: void fill() { cout << "color green"<<endl; } }; class Red:public Color { public: void fill() { cout << "color red"<<endl; } }; class AbFactory // 抽象工廠這里可以實現多個純虛方法 { public: virtual Shape* createShape(string Shape)=0; virtual Color* fillColor(string color)=0; virtual ~AbFactory(){} }; class ShapeFactory:public AbFactory { public: Color* fillColor(string color) { return NULL; } Shape* createShape(string shape) { if(shape=="rectangle"){ return new Rectangle(); } else if(shape == "circle") { return new Circle(); } return NULL; } }; class ColorFactory:public AbFactory { public: Color* fillColor(string color) { if(color=="green"){ return new Green(); } else if(color == "red") { return new Red(); } return NULL; } Shape* createShape(string shape) { return NULL; } }; int main(int argc, char *argv[]) { AbFactory* abfactory; // 創建抽象工廠指針 abfactory = new ShapeFactory(); // 創建繪圖工廠 Shape* shape = abfactory->createShape("rectangle"); //獲取繪制矩形的工具(產品) if(shape == NULL) { cout << "shape is NULL"; } else { shape->draw(); // 使用繪制矩形的產品 } delete shape; delete abfactory; abfactory = new ColorFactory(); // 創建噴漆工廠 Color* color = abfactory->fillColor("red"); //獲取噴紅漆的工具(產品) if(color == NULL) { cout << "color is NULL"; } else { color->fill(); // 使用噴紅漆的產品 } delete color; delete abfactory; return 0; }

 

個人理解:   

0. 封裝了產品的創建,使得不需要知道具體是哪種產品,只需要知道是哪個工廠即可。這點是明顯區分於簡單工廠的。

1.抽象工廠類似總公司,負責規定並建立所有的產品線(即聲明純虛函數),原則上以后不允許再新增產品線,否則需要在該類內部新增純虛函數,這破壞了開閉原則。   

2.繼承於抽象工廠類的具體工廠,根據需要可以選擇性(部分或全部)實現產品線(即上述純虛函數)來創建具體的產品。這是符合開閉原則的,因為此時新增工廠,並不需要修改已有的代碼。   

3. 創建一個具體產品的產品抽象類,具體產品類負責實現該產品抽象類。 

抽象工廠模式可以創建產品組,即:不同子公司(具體工廠類)都嚴格按照產品線來生產產品,然而各自產品線的具體產品可以個性化實現,  同時,一條產品線下的產品,通常存在共性,也就是說,一個產品抽象類通常是需要的,而不是必須的。   

小結: 抽象工廠模式,可以新增工廠(例如ColorFactory類),也可以新增具體產品(例如Rectangle類),但是不建議新增產品線,這會破壞開閉原則,

同時,產品抽象類的功能概念是與產品線的功能概念遙相呼應的存在,雖不是必須的,但通常是需要的。

 

 

文末:

抽象工廠,也可以參考 https://blog.csdn.net/konglongdanfo1/article/details/83380770   文章嘛 多看點好,不同的角度。

 

 

 

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM