大话设计模式
1 原型模式(Prototype)结构图
2 对原型模式的一些解释
2.1 概念:用原型示例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。【DP】
2.2 原型模式实际上就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
2.3 原型模式代码
原型类:
class Prototype
{
private:
string id;
public:
Prototype(string id)
{
this->id = id;
}
string getID()
{
return id;
}
virtual Prototype* Clone();//抽象类关键就是有这样一个Clone方法
};
具体原型类:
class ConcretePrototype1 :public Prototype
{
public:
ConcretePrototype1(string id) :Prototype(id){}
Prototype *Clone() override
{
return this->clone();//创建当前对象的克隆版本,自己定义clone函数,实现深度复制
}
};
- 浅复制:被复制的对象的所有变量都含有与原来的对象相同的值,而所有对其他对象的引用都仍然指向原来的对象。
- 深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
2.5 适用场景
一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,有对性能是大大的提高。因为如果不用Clone,每次new,都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次的执行这个初始化操作就实在是太低效了。
3 原型模式C++实现
题目:复制简历,并能随意修改被赋值的简历而不改变其原始简历
3.1 代码结构图
3.2 C++代码实现
#include<iostream>
#include<string>
using namespace std;
//工作经历类
class WorkExperience
{
private:
string workDate;
string workCompany;
WorkExperience(const WorkExperience *p) :workDate(p->workDate), workCompany(p->workCompany){}//为克隆函数做准备
public:
WorkExperience():workDate(""),workCompany(""){}
WorkExperience(const string wd, const string wc = "XXXX"):workDate(wd), workCompany(wc){}
void setWorkDate(string wd)
{
this->workDate = wd;
}
string getWorkDate()
{
return this->workDate;
}
void setWorkCompany(string wc)
{
this->workCompany = wc;
}
string getWorkCompany()
{
return this->workCompany;
}
WorkExperience *Clone()
{
return new WorkExperience(this);
}
};
//简历类
class Resume
{
private:
string name;
char sex;//'M'代表男性,'F'代表女性
int age;
WorkExperience *workExp;
Resume(WorkExperience *work)//提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据
{
this->workExp = work->Clone();
}
public:
Resume(string na) :name(na), workExp(new WorkExperience()){}
//设置个人信息
void setPersonalInfo(char sex, int age)
{
this->sex = sex;
this->age = age;
}
//设置工作经历信息
void setWorkExperience(string wd, string wc)
{
this->workExp->setWorkDate(wd);
this->workExp->setWorkCompany(wc);
}
//显示
void display()
{
cout << name << " " << sex << " " << age << endl;
cout << "工作经历: " << this->workExp->getWorkDate() << " " << this->workExp->getWorkCompany() << endl;
}
Resume *Clone()
{
Resume *res = new Resume(workExp);
res->age = this->age;
res->name = this->name;
res->sex = this->sex;
return res;
}
};
//客户端
int main()
{
Resume *res = new Resume("大鸟");
res->setPersonalInfo('M', 29);
res->setWorkExperience("1998-2000", "XX Company");
res->display();
cout << endl;
Resume *resCopy1 = res->Clone();
// resCopy1->display();
resCopy1->setWorkExperience("1998-2006", "YY Company");
resCopy1->display();
cout << endl;
Resume *resCopy2 = res->Clone();
// resCopy1->display();
resCopy2->setWorkExperience("1998-2003", "ZZ Company");
resCopy2->display();
cout << endl;
if (res)
{
delete res;
res = nullptr;
}
if (resCopy1)
{
delete resCopy1;
resCopy1 = nullptr;
}
if (resCopy2)
{
delete resCopy2;
resCopy2 = nullptr;
}
system("pause");
return 0;
}
运行结果:
大鸟 M 29
工作经历: 1998-2000 XX Company
大鸟 M 29
工作经历: 1998-2006 YY Company
大鸟 M 29
工作经历: 1998-2003 ZZ Company
请按任意键继续. . .