原型模式
原型模式定义
原型模式,用原型实例指定创建对象的各类,并且通过拷贝这些原型创建新的对象。通俗讲就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。
原型模式何时使用
每次创建new一个对象,都需要执行一次构造函数,如果构造函数的执行时间很长,那么金疮的执行这个初始化操作就实在是太低效了。一般在初始化的信息不发生变化的情况下,克隆是最好的方法,这即隐藏了对象的细节,又对性能是大大的提高。
原型模式结构图
原型模型结构图如下图所示:

图 01 原型模式结构图
原型模式套用代码
1 #include "iostream" 2 using namespace std; 3 class Prototype 4 { 5 private: 6 string id; 7 public: 8 Prototype() 9 { 10 11 } 12 Prototype(string id) 13 { 14 this->id = id; 15 } 16 17 string GetId() 18 { 19 return this->id; 20 } 21 22 void SetId(string id) 23 { 24 this->id = id; 25 } 26 27 virtual Prototype* Clone() = 0; 28 }; 29 30 class concretePrototype1 : public Prototype 31 { 32 public: 33 concretePrototype1() 34 { 35 36 } 37 concretePrototype1(string id) : Prototype(id) 38 { 39 40 } 41 42 virtual Prototype* Clone() 43 { 44 concretePrototype1* p1 = new concretePrototype1(); 45 // 将this指向的对象的值赋给p1指向的对象 46 *p1 = *this; 47 return p1; 48 } 49 }; 50 51 52 void main() 53 { 54 concretePrototype1* p1 = new concretePrototype1("1"); 55 concretePrototype1* p2 = (concretePrototype1*)p1->Clone(); 56 }
原型模式实例应用
本实例包含抽象类:CPrototype ,工作经验类:CWorkExperience ,简介类:CResume。具体关系如下图所示:

图 02 原型模式实例类图
在这里不得不提到浅复制与深复制问题以下是简单的解释:如果字段是值类型(像string,int等),则对该字段执行逐位复制(重新分配一块内存),如果字段是引用类型(class),则复制引用但不复制引用的对象(复制地址,不分配内存),因此,原始对象及其复本引用同一个对象。
原型模式实例应用代码(浅复制)
1 #include "iostream" 2 using namespace std; 3 #include <string> 4 5 class CPrototype 6 { 7 public: 8 virtual CPrototype* Clone() = 0; 9 }; 10 11 class CWorkExperience 12 { 13 private: 14 string workDate; 15 string company; 16 public: 17 void SetWorkDate(string workDate) 18 { 19 this->workDate = workDate; 20 } 21 22 string GetWorkDate() 23 { 24 return this->workDate; 25 } 26 27 void SetCompany(string company) 28 { 29 this->company = company; 30 } 31 32 string GetCompany() 33 { 34 return this->company; 35 } 36 }; 37 38 39 class CResume : public CPrototype 40 { 41 private: 42 string name; 43 string sex; 44 string age; 45 CWorkExperience* work; 46 public: 47 CResume() 48 { 49 50 } 51 CResume(string name) 52 { 53 this->name = name; 54 work = new CWorkExperience(); 55 } 56 57 // 设置个人信息 58 void SetPersonalInfo(string sex, string age) 59 { 60 this->sex = sex; 61 this->age = age; 62 } 63 64 // 设置工作经历 65 void SetWorkExperience(string workDate, string company) 66 { 67 this->work->SetWorkDate(workDate); 68 this->work->SetCompany(company); 69 } 70 71 void display() 72 { 73 cout << " name: " << this->name << " sex: " << this->sex << " age: " << this->age << endl; 74 cout << "work experience: " << this->work->GetWorkDate() << " " << this->work->GetCompany() << endl; 75 } 76 77 virtual CPrototype* Clone() 78 { 79 80 // 浅复制,没有为CWorkExperience对象分配内存 81 CResume* shallowResume = new CResume(); 82 // 将当前对象(this)的内容复制到新申请的对象中(resume) 83 *shallowResume = *this; 84 return shallowResume; 85 86 /* 87 // 这种深复制好理解,但是不好 88 // 深复制,为CWorkExperience对象分配内存 89 CResume* deepResume = new CResume(); 90 *deepResume = *this; 91 deepResume->work = new CWorkExperience(); 92 return deepResume; 93 */ 94 } 95 96 }; 97 98 99 void main() 100 { 101 CResume* resume1 = new CResume("xiao"); 102 resume1->SetPersonalInfo("man", "30"); 103 resume1->SetWorkExperience("2014-11-28", "四川"); 104 105 CResume* resume2 = (CResume*)resume1->Clone(); 106 resume2->SetWorkExperience("2014-10-28", "天津"); 107 108 CResume* resume3 = (CResume*)resume1->Clone(); 109 // 值复制,会重新申请内存,所以值改变了 110 resume3->SetPersonalInfo("women", "40"); 111 // CWorkExperience对象并没有重新申请内存,只是复制了地址, 112 // resume3与resume1的CWorkExperience对象指向同一块内存 113 resume3->SetWorkExperience("2014-9-28", "北京"); 114 115 resume1->display(); 116 resume2->display(); 117 resume3->display(); 118 119 if(resume1 != NULL) 120 { 121 delete resume1; 122 resume1 = NULL; 123 } 124 125 if(resume2 != NULL) 126 { 127 delete resume2; 128 resume2 = NULL; 129 } 130 131 if(resume3 != NULL) 132 { 133 delete resume3; 134 resume3 = NULL; 135 } 136 }
原型模式实例应用代码(深复制)
1 #include "iostream" 2 using namespace std; 3 #include <string> 4 5 class CPrototype 6 { 7 public: 8 virtual CPrototype* Clone() = 0; 9 }; 10 11 class CWorkExperience : public CPrototype 12 { 13 private: 14 string workDate; 15 string company; 16 public: 17 void SetWorkDate(string workDate) 18 { 19 this->workDate = workDate; 20 } 21 22 string GetWorkDate() 23 { 24 return this->workDate; 25 } 26 27 void SetCompany(string company) 28 { 29 this->company = company; 30 } 31 32 string GetCompany() 33 { 34 return this->company; 35 } 36 37 virtual CPrototype* Clone() 38 { 39 CWorkExperience* work = new CWorkExperience(); 40 *work = *this; 41 return work; 42 } 43 }; 44 45 46 class CResume : public CPrototype 47 { 48 private: 49 string name; 50 string sex; 51 string age; 52 CWorkExperience* work; 53 public: 54 CResume() 55 { 56 57 } 58 CResume(string name) 59 { 60 this->name = name; 61 work = new CWorkExperience(); 62 } 63 64 // 设置个人信息 65 void SetPersonalInfo(string sex, string age) 66 { 67 this->sex = sex; 68 this->age = age; 69 } 70 71 // 设置工作经历 72 void SetWorkExperience(string workDate, string company) 73 { 74 this->work->SetWorkDate(workDate); 75 this->work->SetCompany(company); 76 } 77 78 void display() 79 { 80 cout << " name: " << this->name << " sex: " << this->sex << " age: " << this->age << endl; 81 cout << "work experience: " << this->work->GetWorkDate() << " " << this->work->GetCompany() << endl; 82 } 83 84 virtual CPrototype* Clone() 85 { 86 CResume* deepResume = new CResume(); 87 // 将当前对象(this)的内容复制到新申请的对象中(resume) 88 *deepResume = *this; 89 // 为CWorkExperience对象分配新内存 90 deepResume->work = (CWorkExperience*)this->work->Clone(); 91 return deepResume; 92 } 93 94 }; 95 96 97 void main() 98 { 99 CResume* resume1 = new CResume("xiao"); 100 resume1->SetPersonalInfo("man", "30"); 101 resume1->SetWorkExperience("2014-11-28", "四川"); 102 103 CResume* resume2 = (CResume*)resume1->Clone(); 104 resume2->SetWorkExperience("2014-10-28", "天津"); 105 106 CResume* resume3 = (CResume*)resume1->Clone(); 107 // 值复制,会重新申请内存,所以值改变了 108 resume3->SetPersonalInfo("women", "40"); 109 // CWorkExperience对象并没有重新申请内存,只是复制了地址, 110 // resume3与resume1的CWorkExperience对象指向同一块内存 111 resume3->SetWorkExperience("2014-9-28", "北京"); 112 113 resume1->display(); 114 resume2->display(); 115 resume3->display(); 116 117 if(resume1 != NULL) 118 { 119 delete resume1; 120 resume1 = NULL; 121 } 122 123 if(resume2 != NULL) 124 { 125 delete resume2; 126 resume2 = NULL; 127 } 128 129 if(resume3 != NULL) 130 { 131 delete resume3; 132 resume3 = NULL; 133 } 134 }
2014-11-28 16:39:45
浙公网安备 33010602011771号