C++ 工廠模式 分析和總結

簡介

  用一個單獨的類來做創建實例的過程,是工廠;用工廠方法代替new操作的一種模式;工廠模式就相當於創建實例對象的new,我們經常要根據類Class生成實例對象。

分類

簡單工廠模式、工廠方法模式、抽象工廠模式

爲什麼要使用工廠模式?

  1. 程序更規範有條理,當我們創建實例對象時,如果不僅僅做賦值這樣簡單的事情,而是有一大段邏輯,那這個時候我們要將所有的初始化邏輯都寫在構造函數中嗎? 顯然,這樣使得代碼很難看;
  2. 降低耦合度,提高可閱讀性。面向對象的基本思想封裝告訴我們,我們儘量將長的代碼進行"切割",再將每一個小邏輯都"封裝"起來,這樣可以降低耦合度,修改的時候也可以直奔錯誤段落。

1)簡單工廠模式

簡介
簡單工廠模式是屬於創建型模式,又叫做靜態工廠方法(static Factory Method)模式,簡單工廠模式是由一個工廠對象決定創建出來哪一種產品類的實例。

特點
是由一個工廠類根據傳入的參數,動態決定應該創建哪一類產品類(這些產品類繼承自一個父類或接口)的實例;
需要在工廠類中作出判斷,在創建產品的時候,指定響應產品創造。

舉個例子:
假設有一個工廠,他能生產出A、B兩種產品。當客戶需要產品的時候一定要告訴共產是哪種產品,是A還是B。當新增加一種新產品的時候,那麼就要去修改工廠的類。 

應用說明:
一個工廠,多個產品。產品需要有一個虛基類。通過傳入參數,生成具體產品對象,並利用基類指針指向此對象。

程序案例:

#include "stdafx.h"
#include <iostream>

using namespace std;

//類方法—生產的產品
class Product
{
public:
    virtual void show()=0;

}

class  Product_A :public Product   //產品A
{

public:
    void show()
    {

    cout<<"Product_A"<<endl;

    }

};

class Product_B : public Product   //產品B
{

public:
    void show()
    {
        cout<<"Product_B"<<endl;

    }

};

//工廠

class Factory                //只有一家工廠,可以生產不同的產品
{
public:
    Product* Create(int i)
    {
        switch(i)
        {
            case 1:                      //生產產品A
                return new Prodent_A;
                break;

            case 2:                       //生產產品B
                return new Product_B;
                break;
            
            default:
                break;
        }

    }

};

int main()
{
    Factory *factoty = new Factory();   //實例化--工廠對象
    factoty->Create(1)->show();          //指定生產A產品
    factoty->Create(2)->show();          //指定生產B產品
    system("pause");
    return 0;

}

缺點:
每次新增一個類時,都需要改變工廠函數,破壞了封裝性;(如果生產廠家需要新增一個產品,那麼工廠函數Factory就需要跟着改變,所以上面的工廠模式違背了開放封閉原則;)

:開放封閉原則:軟件實體(類、模塊、函數)可以擴展,但是不可修改。

2)工廠方法模式

簡介
多個工廠,多個產品,每個產品對應於一個工廠。此時工廠和產品都是通過虛基類的方式構建。

特點
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。
當增加一個新產品時,同時增加一個新工廠。增加新工廠屬於擴展,不會修改以前工廠類和產品類的任何代碼。可以看過多個獨立的簡單工廠模式構成了工廠方法模式。

舉個例子:
假設現在有A、B兩種產品,那麼久開兩個工廠。工廠A負責生產A產品,工廠B負責生產B種產品。這時候客戶不需要告訴共產生產哪種產品了,只需要告訴共產生產就可以了。

應用說明:
 把簡單工廠模式中的工廠類抽象出一個接口,這個接口只有一個方法,就是創建抽象產品的工廠方法。

程序案例:

#include "stdafx.h"
#include<iostream>

using namespace std;

//類方法—生產的產品
class Product
{
public:
    virtual void show() = 0;  
};

class Product_A : public Product    //產品A
{
public:
    void show()
    {
        cout << "Product_A" << endl;
    }
};

class Product_B : public Product   //產品B
{
public:
    void show()
    {
        cout << "Product_B" << endl;
    }
};

class Factory          //工廠
{
public:
    virtual Product* create() = 0;
};

class Factory_A : public Factory  //工廠A 只有一個函數方法(產品)
{
public:
    Product* create()
    {
        return new Product_A;
    }
};

class Factory_B : public Factory  //工廠B 只有一個函數方法(產品)
{
public:
    Product* create()
    {
        return new Product_B;
    }
};

int main()
{
    Factory_A* productA = new Factory_A();  //實例化--工廠對象A
    Factory_B* productB = new Factory_B();  //實例化--工廠對象B
 
    productA->create()->show();         //工廠A 調用函數(生產產品)
    productB->create()->show();         //工廠B 調用函數(生產產品)
    system("pause");
    return 0;
}

缺點:
每增加一個新的產品,就需要增加一個新的工廠

3)抽象工廠模式

簡介
多個工廠,多個產品,並且每個產品可以包含多個型號。此時工廠和產品都是通過虛基類的方式構建。每一個工廠類可以生產同一個產品的多個型號。

特點
提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

舉個例子:
例1)假如我們A產品中有A1和A2兩種型號的廠品,B產品中有B1和B2兩種型號的廠品,那怎麼辦,上面兩種工廠模式就不能解決了。這個時候抽象工廠模式就登場了。還是開設兩家工廠,工廠A負責生產A1 、A2型號產品,B工廠負責生產B1、B2型號的產品。

例2)假設一種情況,在的家中,某一個衣櫃(具體工廠)只能存放某一種這樣的衣服(成套,一系列具體產品),每次拿這種成套的衣服時也自然要從這個衣櫃中取出了。用 OOP 的思想去理解,所有的衣櫃(具體工廠)都是衣櫃類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產品),褲子(某一具體產品),這些具體的上衣其實也都是上衣(抽象產品),具體的褲子也都是褲子(另一個抽象產品)。

優點:當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。
缺點:產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。

應用說明

#include <iostream>    
using namespace std;  
  
//定義抽象類  
class product1  
{  
public:  
    virtual void show() = 0;  
};  
  
//定義具體類  
class product_A1 :public product1  
{  
public:  
    void show(){ cout << "product A1" << endl; }  
};  
  
class product_B1 :public product1  
{  
public:  
    void show(){ cout << "product B1" << endl; }  
};  
  
//定義抽象類  
class product2  
{  
public:  
    virtual void show() = 0;  
};  
  
//定義具體類  
class product_A2 :public product2  
{  
public:  
    void show(){ cout << "product A2" << endl; }  
};  
  
class product_B2 :public product2  
{  
public:  
    void show(){ cout << "product B2" << endl; }  
};  
  
  
class Factory                //工廠
{  
public:  
    virtual product1 *creat1() = 0;  
    virtual product2 *creat2() = 0;  
};  
  
class FactoryA                    //工廠A 可以有多個函數方法(產品)
{  
public:  
    product1 *creat1(){ return new product_A1(); }  
    product2 *creat2(){ return new product_A2(); }  
};  
  
class FactoryB                   //工廠B 可以有多個函數方法(產品)
{  
public:  
    product1 *creat1(){ return new product_B1(); }  
    product2 *creat2(){ return new product_B2(); }  
};  
  
int main()  
{  
    FactoryA *factoryA = new FactoryA();     //實例化--工廠對象A
    factoryA->creat1()->show();              //工廠A 調用函數(生產產品1)
    factoryA->creat2()->show();              //工廠A 調用函數(生產產品2)
  
    FactoryB *factoryB = new FactoryB();     //實例化--工廠對象B
    factoryB->creat1()->show();              //工廠B 調用函數(生產產品1)
    factoryB->creat2()->show();              //工廠B 調用函數(生產產品2)
  
    return 0;  
}

優點:
易於交換產品系列,由於具體工廠類在一個應用中只需要在初始化的時候出現一次,這樣就使得改變一個應用的具體工廠變得非常容易,只需要改變具體工廠即可使用不同的產品配置。
讓具體的創建實例過程與客戶端分離,客戶端是通過它們的抽象接口操縱實例,產品的具體類名也被具體工廠實現分離,不會出現在客戶代碼中。

缺點:
增加新的產品時需要改動多處代碼。

希望你對有幫助;
如發現有錯誤的,歡迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章