“對象創建” 模式
- 通過“對象創建” 模式繞開new,來避免對象創建(new)過程中所導致的緊耦合(依賴具體類),從而支持對象創建的穩定。它是接口抽象之後的第一步工作。
- 典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
動機(Motivation)
- 在軟件系統中,經常面臨着創建對象的工作;由於需求的變化,需要創建的對象的具體類型經常變化。
- 如何應對這種變化?如何繞過常規的對象創建方法(new),提供一種“封裝機制”來避免客戶程序和這種“具體對象創建工作”的緊耦合?
模式定義
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。Factory Method使得一個類的實例化延遲(目的:解耦,手段:虛函數)到子類。 ——《設計模式》GoF
結構(Structure)
要點總結
- Factory Method模式用於隔離類對象的使用者和具體類型之間的耦合關係。面對一個經常變化的具體類型,緊耦合關係(new)會導致軟件的脆弱。
- Factory Method模式通過面向對象的手法,將所要創建的具體對象工作延遲到子類,從而實現一種擴展(而非更改)的策略,較好地解決了這種緊耦合關係。
- Factory Method模式解決“單個對象”的需求變化。缺點在於要 求創建方法/參數相同。
原始例子
class MainForm : public Form
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_Click(){
ISplitter * splitter=
new BinarySplitter();//依賴具體類
splitter->split();
}
};
class ISplitter {
public:
virtual void split() = 0;
virtual ~ISplitter();
};
class BinarySplitter : public ISplitter
{
public:
void split() {
//...
}
};
class TxtSplitter : public ISplitter{
};
class PictureSplitter : public ISplitter{
};
class VideoSplitter : public ISplitter{
};
修改後的代碼
#include "FileSplitterFactory.cpp"
class MainForm : public Form
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
SplitterFactory* factory;
public:
MainForm(SplitterFactory* factory) {
this->factory = factory;
}
void Button1_Click(){
ISplitter* splitter =
factory->CreateSplitter();
splitter->split();
}
};
//抽象類
class ISplitter {
public:
virtual void split() = 0;
virtual ~ISplitter();
};
//工廠基類
class SplitterFactory {
public:
virtual ISplitter* CreateSplitter() = 0;
virtual ~SplitterFactory() {}
};
#include "FileSplitterFactory.cpp"
//具體類
class BinarySplitter : public ISplitter
{
public:
void split() {
//...
}
};
class TxtSplitter : public ISplitter {
};
class PictureSplitter : public ISplitter {
};
class VideoSplitter : public ISplitter {
};
//具體工廠
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 VedioSplitterFactory : public SplitterFactory {
public:
virtual ISplitter* CreateSplitter() {
return new VideoSplitter();
}
};