天天看點

三種工廠模式詳解 别隻知道政策模式+簡單工廠,試試更香的政策模式+抽象工廠!

我的相關博文:

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   文章嘛 多看點好,不同的角度。

.