標籤:應聘 開始 步驟 函數 protected 接受 class 拷貝 using
DP書上的定義為:用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。其中有一個詞很重要,那就是拷貝。可以說,拷貝是原型模式的精髓所在。舉個現實中的例子來介紹原型模式。找工作的時候,我們需要準備簡曆。假設沒有列印裝置,因此需手寫簡曆,這些簡曆的內容都是一樣的。這樣有個缺陷,如果要修改簡曆中的某項,那麼所有已寫好的簡曆都要修改,工作量很大。隨著科技的進步,出現了列印裝置。我們只需手寫一份,然後利用列印裝置複印多份即可。如果要修改簡曆中的某項,那麼修改原始的版本就可以了,然後再複印。原始的那份手寫稿相當於是一個原型,有了它,就可以通過複印(拷貝)創造出更多的新簡曆。這就是原型模式的基本思想。下面給出原型模式的UML圖,以剛才那個例子為執行個體。
原型模式實現的關鍵就是實現Clone函數,對於C++來說,其實就是拷貝建構函式,需實現深拷貝,下面給出一種實現。
#include<iostream>#include <string.h>using namespace std;//父類class Resume{protected: char *name;public: Resume() {} virtual ~Resume() {} virtual Resume* Clone() { return NULL; } virtual void Set(char *n) {} virtual void Show() {}};class ResumeA : public Resume{public: ResumeA(const char *str); //建構函式 ResumeA(const ResumeA &r); //拷貝建構函式 ~ResumeA(); //解構函式 ResumeA* Clone(); //複製,關鍵所在 void Show(); //顯示內容};ResumeA::ResumeA(const char *str){ if(str == NULL) { name = new char[1]; name[0] = ‘\0‘; } else { name = new char[strlen(str)+1]; strcpy(name, str); }}ResumeA::~ResumeA() { delete [] name;}ResumeA::ResumeA(const ResumeA &r) { name = new char[strlen(r.name)+1]; strcpy(name, r.name);}ResumeA* ResumeA::Clone() { return new ResumeA(*this);}void ResumeA::Show() { cout<<"ResumeA name : "<<name<<endl;}class ResumeB : public Resume{public: ResumeB(const char *str); //建構函式 ResumeB(const ResumeB &r); //拷貝建構函式 ~ResumeB(); //解構函式 ResumeB* Clone(); //複製,關鍵所在 void Show(); //顯示內容};ResumeB::ResumeB(const char *str){ if(str == NULL) { name = new char[1]; name[0] = ‘\0‘; } else { name = new char[strlen(str)+1]; strcpy(name, str); }}ResumeB::~ResumeB() { delete [] name;}ResumeB::ResumeB(const ResumeB &r) { name = new char[strlen(r.name)+1]; strcpy(name, r.name);}ResumeB* ResumeB::Clone() { return new ResumeB(*this);}void ResumeB::Show() { cout<<"ResumeB name : "<<name<<endl;}int main(){ Resume *r1 = new ResumeA("A"); Resume *r2 = new ResumeB("B"); Resume *r3 = r1->Clone(); Resume *r4 = r2->Clone(); r1->Show(); r2->Show(); //刪除r1,r2 delete r1; delete r2; r1 = r2 = NULL; //深拷貝所以對r3,r4無影響 r3->Show(); r4->Show(); delete r3; delete r4; r3 = r4 = NULL;}原型模式
最近有個招聘會,可以帶上簡曆去應聘了。但是,其中有一家公司不接受簡曆,而是給應聘者發了一張簡曆表,上面有基本資料、教育背景、工作經曆等欄,讓應聘者按照要求填寫完整。每個人拿到這份表格後,就開始填寫。如果用程式實現這個過程,該如何做呢?一種方案就是用模板方法模式:定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。我們的例子中,操作就是填寫簡曆這一過程,我們可以在父類中定義操作的演算法骨架,而具體的實現由子類完成。下面給出它的UML圖。
其中FillResume() 定義了操作的骨架,依次調用子類實現的函數。相當於每個人填寫簡曆的實際過程。接著給出相應的C++代碼。
#include<iostream>#include <string.h>using namespace std;//簡曆class Resume{protected: //保護成員 virtual void SetPersonalInfo() {} virtual void SetEducation() {} virtual void SetWorkExp() {}public: void FillResume() { SetPersonalInfo(); SetEducation(); SetWorkExp(); }};class ResumeA: public Resume{protected: void SetPersonalInfo() { cout<<"A‘s PersonalInfo"<<endl; } void SetEducation() { cout<<"A‘s Education"<<endl; } void SetWorkExp() { cout<<"A‘s Work Experience"<<endl; }};class ResumeB: public Resume{protected: void SetPersonalInfo() { cout<<"B‘s PersonalInfo"<<endl; } void SetEducation() { cout<<"B‘s Education"<<endl; } void SetWorkExp() { cout<<"B‘s Work Experience"<<endl; }};int main(){ Resume *r1; r1 = new ResumeA(); r1->FillResume(); delete r1; r1 = new ResumeB(); r1->FillResume(); delete r1; r1 = NULL; return 0;}模板模式
C++原型模式和模板模式