5原型模式

原型模式

为什么需要原型模式?

现在有一个简历 Resume 类,如果要批量复制简历对象,有哪些方法呢?

#include <iostream>

class Resume {
private:
std::string name;
std::string sex;
std::string age;
public:
Resume() {};
void SetPersonalInfo(const std::string& name, const std::sting& age)
{
this.name = name;
this.age = age;
}

};

int main()
{
Resume p1;
p1.SetPersonalInfo("zhangsan", "25");
Resume p2;
p2.SetPersonalInfo("zhangsan", "25");
}

上述实现方式非常简单又容易理解,你需要几份简历,就定义几个简历对象。

但是,这里有一个很严重的问题:一旦简历内容需要修改,那么所有的简历对象都需要改动。原型模式正是为了解决它而出现的。

原型模式

原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

#include <iostream>

class Resume {
private:
std::string name;
std::string age;
std::string education;
public:
Resume()
{
std::cout << "Construct !" << std::endl;
};
Resume(const Resume& resume)
{
this->name = resume.name;
this->age = resume.age;
this->education = resume.education;
std::cout << "Copy Construct !" << std::endl;
}
void SetPersonalInfo(const std::string& name, const std::string& age)
{
this->name = name;
this->age = age;
}
void SetEducation(const std::string& educatoin)
{
this->education = educatoin;
}
void PrintResume()
{
std::cout << name << ", " << age << ", " << education << std::endl;
}
Resume* Clone()
{
return new Resume(*this);
}
};

int main()
{
Resume* p1 = new Resume();
p1->SetPersonalInfo("Tom", "25");
p1->SetEducation("master");
p1->PrintResume();

Resume* p2 = p1->Clone();
p2->SetPersonalInfo("Jack", "28");
p2->PrintResume();
}

当我们定义了第一个简历对象 p1 时,如果再需要创建一个对象,直接调用 p1 中的克隆 Clone 方法,然后返回一个新的对象 p2. 如果想要定制化简历 p2 时,只需要在 p2 中修改与 p1 差异的地方就可以了。而 Clone 一定要借助于拷贝构造函数才能实现。

所以,一般在初始化的信息不发生变化的情况下,克隆是最好的办法,这既隐藏了对象创建的细节,又对性能能是大大的提升。

注意!!

有同学可能会说,直接调用拷贝构造函数是不是就可以了,何必在外层封装一层 Clone?实际上,这是有本质区别的。敲黑板,重点来了!

原型模式实现的是一个Clone 接口,注意是接口,也就是基于多态的 Clone 虚函数。也就是说原型模式能够通过基类指针来复制派生类对象。拷贝构造函数完不成这样的任务。在继承场景下,Clone 函数可以定义为虚函数。

virtual Resume* Clone()
{
return new Resume(*this);
}