**定義:**原型模式(Prototype Pattern),用原型模式指定創建對象的種類,并且通過拷貝這些原型創建新的對象。
**類型:**創建型模式。
**類圖:**

**參與角色**:
1. CPrototype,抽象原型基類,提供一個Clone的接口以及一些設置顯示的接口。
1. CConcretePrototype,聲明定義原型的相關參數,并實現Clone接口,主要是通過實現拷貝構造函數來完成的。
另外實現其他接口。
1. Client,首先定義一個原型對象,然后以此為原型克隆新的對象。
**概述:**
?????? 如果只是為了更快的完成新對象的生成,其實就沒必要使用原型模式了。因為可以直接使用拷貝構造函數即可。而使用原型模式最重要的原因是隔離Client去了解具體的實現類,降低模塊間的耦合。Client只需要知道一個抽象類的指針,不僅可以操作具體各咱方法,另外也還可以生成新的對象。
?????? 另外,使用拷貝構造函數時,需要注意深拷貝及淺拷貝。淺拷貝,即按位進行拷貝,即兩個對象的每一個成員變量是相同的。深拷貝,自定義拷貝,一般會處理指針,引用等類型,保證它們有相同的值,而不是它們本身相同。
?????? 有一批Thinkpad電腦,除了內存和硬盤容量外,其他配置都相同。我們可以通過原型對象生成新的對象,并且不需要知道具體的實現類名。
**代碼:**
// 提供接口
~~~
class CPrototype
{
public:
virtual CPrototype* Clone() = 0;
virtual void Show() = 0;
virtual void SetRam(int _nRam) = 0;
virtual void SetRom(int _nRom) = 0;
};
~~~
// 電腦的基本配置信息類
~~~
class CComputerConfig : public CPrototype
{
public:
CComputerConfig(char* _szName, int _nRomSize, int _nRamSize) : m_nRomSize(_nRomSize), m_nRamSize(_nRamSize)
{
if (NULL != _szName)
{
size_t nSize = strlen(_szName) + 1;
m_szComputerName = new char[nSize];
strcpy_s(m_szComputerName, nSize, _szName);
}
else
{
m_szComputerName = NULL;
}
}
~CComputerConfig()
{
if (NULL != m_szComputerName)
{
delete m_szComputerName;
}
}
CComputerConfig(const CComputerConfig& _other)
{
if (NULL == _other.m_szComputerName)
{
m_szComputerName = NULL;
}
else
{
size_t nSize = strlen(_other.m_szComputerName) + 1;
m_szComputerName = new char[nSize];
strcpy_s(m_szComputerName, nSize, _other.m_szComputerName);
m_nRomSize = _other.m_nRomSize;
m_nRamSize = _other.m_nRamSize;
}
}
virtual CPrototype* Clone()
{
return new CComputerConfig(*this);
}
virtual void Show()
{
cout<<m_szComputerName<<",Ram "<<m_nRamSize<<",Rom "<<m_nRomSize<<endl;
}
virtual void SetRam(int _nRam)
{
m_nRamSize = _nRam;
}
virtual void SetRom(int _nRom)
{
m_nRomSize = _nRom;
}
public:
char* m_szComputerName;
int m_nRomSize;
int m_nRamSize;
};
~~~
// 客戶端
~~~
int _tmain(int argc, _TCHAR* argv[])
{
// ThindPad系列電腦
CComputerConfig computer("Thinkpad", 500, 2);
// 原型
CPrototype* pPrototype = &computer;
pPrototype->Show();
// ThindPad系列的2G內存版,500G硬盤版
CPrototype* p2GComputer = computer.Clone();
p2GComputer->SetRam(4);
p2GComputer->Show();
// 4G內存,1T硬盤版
CPrototype* p1TCompter = computer.Clone();
p1TCompter->SetRam(8);
p1TCompter->SetRom(1024);
p1TCompter->Show();
return 0;
}
~~~
**使用場合:**
1. 兩個模塊A,B,模塊B對外暴露一個對象C指針。而模塊A需要建立很多很多C的對象,但是不需要知道具體的C是如何創建的。這個時候就應該使用原型模式。
優缺點:
1. 優點,能夠降低模塊間的耦合性,另外能夠快速的創建新對象。
缺點,改造一個已有類型時,需要細心考慮所有成員變量拷貝的問題,容易遺漏造成錯誤。
**參考資料:**
1. 《設計模式——可復用面向對象軟件基礎》
1. 《Java與模式》
1. 《大話設計模式》
- 前言
- 設計模式六大原則
- 1——創建型模式之簡單工廠模式
- 2——創建型模式之工廠方法模式
- 3——創建型模式之抽象工廠模式
- 4——創建型模式之單例模式
- 5——創建型模式之建造者模式
- 6——創建型模式之原型模式
- 7——結構型模式之適配器模式
- 8——結構型模式之橋接模式
- 9——結構型模式之組合模式
- 10——結構型模式之裝飾者模式
- 11——結構型模式之外觀模式
- 12——結構型模式之享元模式
- 13——結構型模式之代理模式
- 14——行為型模式之職責鏈模式
- 15——行為型模式之命令模式
- 16——行為型模式之解釋器模式
- 17——行為型模式之迭代器模式
- 18——行為型模式之中介者模式
- 19——行為型模式之備忘錄模式
- 20——行為型模式之觀察者模式
- 21——行為型模式之狀態模式
- 22——行為型模式之策略模式
- 23——行為型模式之模板方法模型
- 24——行為型模式之訪問者模式
- 設計模式總結