“對象建立”模式
- 通過“對象建立” 模式繞開new,來避免對象建立(new)過程中所導緻的緊耦合(依賴具體類),進而支援對象建立的穩定。它是接口抽象之後的第一步工作。
- 典型模式
- Factory Method
- Abstract Factory
- Prototype
- 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模式用于隔離類對象的使用者和具體類型之間的 耦合關系。面對一個經常變化的具體類型,緊耦合關系(new)會導 緻軟體的脆弱。
- Factory Method模式通過面向對象的手法,将所要建立的具體對 象工作延遲到子類,進而實作一種擴充(而非更改)的政策,較好地解決了這種緊耦合關系。
- Factory Method模式解決“單個對象”的需求變化。缺點在于要 求建立方法/參數相同。 //參數不同,就永不了。