原型模式(Prototype)
原型模式是一種創(chuàng)建型設(shè)計(jì)模式,其功能為復(fù)制一個(gè)運(yùn)行時(shí)的對(duì)象,包括對(duì)象各個(gè)成員當(dāng)前的值。而代碼又能保持獨(dú)立性。
場景
舉例
假設(shè)這樣一個(gè)場景,孫悟空出世,在花果山經(jīng)歷與猴孫的生死離別后,拜菩提老祖為師。歷經(jīng)多年,學(xué)的一身本領(lǐng)。此時(shí)的悟空拔出一個(gè)毫毛,變出一個(gè)自己。
分析
此時(shí)悟空變出的另一個(gè)自己,自然要與現(xiàn)在的年齡、身高、體重等多個(gè)參數(shù)一致。如果不加設(shè)計(jì),這些代碼可能散落在客戶端函數(shù)。假如過了十年繼續(xù)施展分身,又需重新增加這些代碼。日積月累,這些終將成為晦澀而又難以維護(hù)的“一坨”。
實(shí)現(xiàn)
對(duì)于上述場景就有必要引入原型模式,原型模式的設(shè)計(jì)也是比較簡單的。只需要在類的設(shè)計(jì)時(shí)增加一個(gè)clone接口,用于返回當(dāng)前對(duì)象this指針。客戶端在使用時(shí),只需要對(duì)象的clone接口,就能拿到當(dāng)前對(duì)象的各個(gè)成員值。
類圖
原型模式
通過原型模式基類規(guī)范具備復(fù)制接口的子類實(shí)現(xiàn)。
源碼
#include <iostream>#include <string>
using namespace std;
class CPrototype{public:
CPrototype() {}
~CPrototype() {}
virtual CPrototype* Clone() = 0;};
class CWukong : CPrototype{public: CWukong() : mAge(0), mHeightCM(100), mHair(10000), mLockRing(0), mFightCapacity (20) {
}
CWukong(CWukong *rhs) { mName = rhs->mName; mAge = rhs->mAge; mHeightCM = rhs->mHeightCM; mHair = rhs->mHair; mLockRing = rhs->mLockRing; mFightCapacity = rhs->mFightCapacity; }
virtual ~CWukong() {}
void SetName(string value) { mName = value; }
void AddAge(int value) { mAge += value; }
void SetHeight(int value) { mHeightCM = value; }
void SetHair(int value) { mHair = value; }
void PutLockRing() { mLockRing = 1; }
void RemoveLockRing() { mLockRing = 0; }
void SetFightCapacity(int value) { mFightCapacity = value; }
string GetName() { return mName; }
int GetAge() { return mAge; }
int GetHeight() { return mHeightCM; }
int GetHair() { return mHair; }
int GetLockRing() { return mLockRing; }
int GetFightCapacity() { return mFightCapacity; }
CWukong* Clone(){return new CWukong(*this); }
private:string mName;int mAge;int mHeightCM;int mHair;bool mLockRing;int mFightCapacity;};
static void learn_skills(CWukong *pMonkey){//After 11 years of study, Wukong's parameters change pMonkey->SetName("Wukong.Sun"); pMonkey->AddAge(11); pMonkey->SetHeight(150); pMonkey->SetFightCapacity(80);}
static void show_params(CWukong *pMonkey){cout << ">> " << pMonkey->GetName() << endl;cout << "Age: " << pMonkey->GetAge() << endl;cout << "Height(cm): " << pMonkey->GetHeight() << endl;cout << "Hair: " << pMonkey->GetHair() << endl;cout << "LockRing: " << pMonkey->GetLockRing() << endl;cout << "FightCapacity: " << pMonkey->GetFightCapacity() << endl;cout << " " << endl;}
int main (int argc, char *argv[]){ CWukong *theWukong = new CWukong();//Before Learning, show paramscout << "Before Learning" << endl; show_params(theWukong);
//At the age of five, he went to learn skills theWukong->AddAge(5); theWukong->SetHeight(120); learn_skills(theWukong);//Return after Learning, show params show_params(theWukong);
//Show multitasking skillscout << "Clone Wukong" << endl; CWukong *theWukong2 = theWukong->Clone(); show_params(theWukong2);
delete theWukong2;delete theWukong;return 0;}
輸出
Before Learning>> Age: 0Height(cm): 100Hair: 10000LockRing: 0FightCapacity: 20
>> Wukong.SunAge: 16Height(cm): 150Hair: 10000LockRing: 0FightCapacity: 80
Clone Wukong>> Wukong.SunAge: 16Height(cm): 150Hair: 10000LockRing: 0FightCapacity: 80
實(shí)現(xiàn)流程
- 首先需要在父類定義 克?。╟lone) 純虛接口,子類需要在此接口中返回新創(chuàng)建的子類對(duì)象。
- 子類中,增加一個(gè)以此類對(duì)象為參數(shù)的構(gòu)造函數(shù)。用于保存當(dāng)前所有成員變量值到新創(chuàng)建的對(duì)象中。
- 子類的克隆接口,創(chuàng)建新的對(duì)象時(shí),需要顯示調(diào)用具備子類對(duì)象參數(shù)的構(gòu)造函數(shù)。保證新的對(duì)象中,所有的成員都被初始化。
總結(jié)
- 原型模式能夠克隆一個(gè)對(duì)象,而類之間無需耦合。
- 客戶代碼在復(fù)制復(fù)雜的對(duì)象時(shí),也更加方便。
- 此接口可重復(fù)使用,讓代碼邏輯更加清晰易懂。
- ?
本文摘自 :https://blog.51cto.com/u