006 --- 第9章 原型模式
简述:
原型模式用原型实例指定创建对象的种类,并且通过考北这些原型创建新的对象。
原型模式包括:抽象原型类、具体原型类。
抽象原型类:声明一个克隆自身的接扣。
具体原型类:继承自抽象原型类,实现一个克隆自身的操作。
应用场景:一般在初始化的信息不发生变化的情况下,克隆是最好的办法,既隐藏了创建对象的细节,又对性能是大大的提高
注:开发环境调整为VS2017,操作系统win11
原型模式代码:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 // 原型模式 6 // 抽象原型类 7 class CPrototype 8 { 9 private: 10 string m_szID; 11 12 public: 13 CPrototype() {} 14 15 CPrototype(string szID) 16 { 17 m_szID = szID; 18 } 19 20 void SetID(string szID) 21 { 22 m_szID = szID; 23 } 24 25 string GetID() 26 { 27 return m_szID; 28 } 29 30 virtual CPrototype& Clone() = 0; 31 }; 32 33 // 具体原型类 34 class CConcretePrototype : public CPrototype 35 { 36 public: 37 CConcretePrototype() {} 38 39 CConcretePrototype(string szID) : CPrototype(szID) {} 40 41 virtual CPrototype& Clone() 42 { 43 return (CPrototype&)*this; 44 } 45 }; 46 47 int main() 48 { 49 CConcretePrototype ConcretePrototype1("GHL"); 50 CConcretePrototype ConcretePrototype2 = (CConcretePrototype&)ConcretePrototype1.Clone(); 51 ConcretePrototype2.SetID("GGG"); 52 cout << ConcretePrototype1.GetID() << endl; 53 cout << ConcretePrototype2.GetID() << endl; 54 55 system("pause"); 56 return 0; 57 }
输出结果:
例:简历的克隆
注:本例在clone()函数中需要用到深拷贝,C#中可以继承ICloneable接口进行实现,但C++需要自己实现。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 // 工作经历 6 class CWorkExperience 7 { 8 private: 9 string m_szWorkDate; 10 string m_szCompany; 11 12 public: 13 void SetWorkDate(string szWorkDate) 14 { 15 m_szWorkDate = szWorkDate; 16 } 17 string GetWorkDate() 18 { 19 return m_szWorkDate; 20 } 21 22 void SetCompany(string szCompany) 23 { 24 m_szCompany = szCompany; 25 } 26 string GetCompany() 27 { 28 return m_szCompany; 29 } 30 31 CWorkExperience* Clone() 32 { 33 CWorkExperience* pWorkExperience = new CWorkExperience(); 34 pWorkExperience->SetWorkDate(GetWorkDate()); 35 pWorkExperience->SetCompany(GetCompany()); 36 return pWorkExperience; 37 } 38 }; 39 40 // 简历(具体原型类) 41 class CResume 42 { 43 private: 44 string m_szName; 45 string m_szSex; 46 string m_szAge; 47 CWorkExperience* m_pWorkExperience; 48 49 CResume(CWorkExperience* pWorkExperience) : m_pWorkExperience(NULL) 50 { 51 m_pWorkExperience = pWorkExperience->Clone(); 52 } 53 54 public: 55 CResume() : m_pWorkExperience(NULL) {} 56 57 CResume(string szName) : m_pWorkExperience(NULL) 58 { 59 m_szName = szName; 60 m_pWorkExperience = new CWorkExperience(); 61 } 62 63 ~CResume() 64 { 65 if (m_pWorkExperience) 66 { 67 delete m_pWorkExperience; 68 m_pWorkExperience = NULL; 69 } 70 } 71 72 void SetPersionalInfo(string szSex, string szAge) 73 { 74 m_szSex = szSex; 75 m_szAge = szAge; 76 } 77 78 void SetWorkExperience(string szWorkDate, string szCompany) 79 { 80 m_pWorkExperience->SetWorkDate(szWorkDate); 81 m_pWorkExperience->SetCompany(szCompany); 82 } 83 84 void Display() 85 { 86 cout << m_szName << " " << m_szSex << " " << m_szAge << endl; 87 cout << "工作经历: " << m_pWorkExperience->GetWorkDate() << " " 88 << m_pWorkExperience->GetCompany() << endl << endl; 89 } 90 91 CResume* Clone() 92 { 93 CResume* pResume = new CResume(m_pWorkExperience->Clone()); 94 pResume->m_szName = m_szName; 95 pResume->m_szSex = m_szSex; 96 pResume->m_szAge = m_szAge; 97 return pResume; 98 } 99 }; 100 101 int main() 102 { 103 CResume* pResume1 = new CResume("GHL"); 104 pResume1->SetPersionalInfo("男", "29"); 105 pResume1->SetWorkExperience("2018-2020", "MMM"); 106 107 CResume* pResume2 = pResume1->Clone(); 108 pResume2->SetWorkExperience("2016-2018", "BBB"); 109 110 pResume1->Display(); 111 pResume2->Display(); 112 113 if (pResume1) 114 { 115 delete pResume1; 116 pResume1 = NULL; 117 } 118 if (pResume2) 119 { 120 delete pResume2; 121 pResume2 = NULL; 122 } 123 124 system("pause"); 125 return 0; 126 }
输出结果: