原型模式

原型模式定义

原型模式,用原型实例指定创建对象的各类,并且通过拷贝这些原型创建新的对象。通俗讲就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。

原型模式何时使用

每次创建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 原型模式实例类图

在这里不得不提到浅复制与深复制问题以下是简单的解释:如果字段是值类型(像stringint等),则对该字段执行逐位复制(重新分配一块内存),如果字段是引用类型(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

posted on 2014-11-28 16:24  xiaoheike  阅读(225)  评论(0)    收藏  举报

导航