對象創建模式之工廠方法模式(Factory Method)

一、概念

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

二、動機

  在軟件系統中,經常面臨這創建對象的工作;由於需求的變化,需要創建的對象的具體類型經常變化

  如何應對這種變化?如何繞過常規的對象創建方法(new),提供一種“封裝機制”來避免客戶程序和這種“具體對象創建工作”的緊耦合

三、源代碼講解

class FileSplitter
{
public:
    void split(){
        //...
    }
};

class MainForm : public Form
{
    TextBox* txtFilePath;    //文件路徑
    TextBox* txtFileNumber;    //希望分割的個數
    ProgressBar* progressBar;

public:
    void Button1_Click(){
        //收集到用戶輸入的參數信息
        string filePath = txtFilePath->getText();    
        int number = atoi(txtFileNumber->getText().c_str());
        //傳遞給FileSplitter,讓該類去分割文件
        FileSplitter splitter(filePath, number, progressBar);
        //進行分割
        splitter.split();
    }
};

  動態看待問題,上面使用了具體細節類,是靜態特質,定死了,我們應該去判斷業務有沒有需求的變化,是不是隻需要文件分割。比如我們這裏有變化,支持二進制,圖片,視頻,文本分割…,此時我們應該將他聲明爲抽象基類來使用。

四、使用工廠方法模式進行改進

class MainForm : public Form {
    SplitterFactory *factory; // 工廠
public:
    MainForm(SplitterFactory *factory) {
        this->factory = factory;
    }
    
    void Button1_Click() {
    	// 通過虛函數來實現多態new,避免直接使用new創建對象
        ISplitter *splitter = factory->CreateSplitter(); 
        splitter->split();
    }
};

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

// 具體類
class BinarySplitter : public ISplitter {

};

class TxtSplitter: public ISplitter {
    
};

class PictureSplitter: public ISplitter {

};

class VideoSplitter: public ISplitter {
    
};

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

// 具體工廠
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();
    }
};

五、類圖結構

在這裏插入圖片描述

六、要點總結

  • Factory Method 模式用於隔離類對象的使用者和具體類型之間的耦合關係。面對一個經常變化的具體類型,緊耦合關係(new)會導致軟件的脆弱。

  • Factory Method模式通過面向對象的手法(多態),將所要創建的對象工作延遲到子類,從而實現一種擴展(而非更改)的策略,較好地解決了這種緊耦合關係。

  • Factory Method模式解決“單個對象”的需求變化。缺點在於要求創建方法/參數相同

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