天天看點

工廠方法模式 Factory Method

“對象建立”模式

  • 通過“對象建立” 模式繞開new,來避免對象建立(new)過程中所導緻的緊耦合(依賴具體類),進而支援對象建立的穩定。它是接口抽象之後的第一步工作。
  • 典型模式
  1. Factory Method
  2. Abstract Factory
  3. Prototype
  4. Builder

動機(Motivation)

  • 在軟體系統中,經常面臨着建立對象的工作;由于需求的變化,需要建立的對象的具體類型經常變化。
  • 如何應對這種變化?如何繞過正常的對象建立方法(new),提供一種“封裝機制”來避免客戶程式和這種“具體對象建立工作”的緊耦合?

把變化類比一個兔子,把他趕到一個籠子裡,讓它隻在籠子裡變化,這就隔離了變化,在局部(籠子)管理的變化。不要讓變化在整個代碼中跳來跳去。

模式定義

定義一個用于建立對象的接口,讓子類決定執行個體化哪一個類。Factory Method使得一個類的執行個體化延遲(目的:解耦,手段:虛函數)到子類。 ——《設計模式》GoF

代碼示例

基于前面那個檔案分解的示例。

#include <iostream>
using namespace std;

//抽象類
class ISplitter {
public:
    virtual void split() = 0;
    virtual ~ISplitter() {}
};

//工廠基類
class SplitterFactory {
public:
    virtual ISplitter* CreateSplitter() = 0;
    virtual ~SplitterFactory() {}
};

//具體類
class BinarySplitter : public ISplitter {
public:
    virtual void split()
    {
        cout << "分解" << "二進制檔案" << endl;
    }
};

class TxtSplitter : public ISplitter {
public:
    virtual void split()
    {
        cout << "分解" << "文本檔案" << endl;
    }
};

class PictureSplitter : public ISplitter {
public:
    virtual void split()
    {
        cout << "分解" << "圖檔檔案" << endl;
    }
};

class VideoSplitter : public ISplitter {
public:
    virtual void split()
    {
        cout << "分解" << "視訊檔案" << endl;
    }
};

//具體工廠    子類決定執行個體化哪個類
class BinarySplitterFactory : public SplitterFactory {
public:
    virtual ISplitter* CreateSplitter() {
        return new BinarySplitter();
    }
};

class TxtSplitterFactory : public SplitterFactory {
public:
    virtual ISplitter* CreateSplitter() {
        return new TxtSplitter();
    }
};

class PictureSplitterFactory : public SplitterFactory {
public:
    virtual ISplitter* CreateSplitter() {
        return new PictureSplitter();
    }
};

class VideoSplitterFactory : public SplitterFactory {
public:
    virtual ISplitter* CreateSplitter() {
        return new VideoSplitter();
    }
};

/********************/
// MianForm 這個類至少是不再變化了,把變化趕到工廠那邊去了。
class MainForm /*: public Form*/
{
private:
    SplitterFactory*  factory;//工廠

public:
    MainForm(SplitterFactory*  factory) {
        this->factory = factory;
    }
    ~MainForm() {
        if (factory != nullptr) {
            delete factory;
            factory = nullptr;
      }
    void Button1_Click() {
        ISplitter * splitter =
            factory->CreateSplitter(); //多态new

        splitter->split();
    }
};

int main()
{
    VideoSplitterFactory videoSpFactor;
    MainForm mainForm(&videoSpFactor);
    mainForm.Button1_Click();

    getchar();
    return 0;
}      

輸出:

分解視訊檔案      

類圖

工廠方法模式 Factory Method

要點總結

  1. Factory Method模式用于隔離類對象的使用者和具體類型之間的 耦合關系。面對一個經常變化的具體類型,緊耦合關系(new)會導 緻軟體的脆弱。
  2. Factory Method模式通過面向對象的手法,将所要建立的具體對 象工作延遲到子類,進而實作一種擴充(而非更改)的政策,較好地解決了這種緊耦合關系。
  3. Factory Method模式解決“單個對象”的需求變化。缺點在于要 求建立方法/參數相同。 //參數不同,就永不了。