一、什么是原型模式
原型模式是指:创建对象的种类,并通过拷贝这些原型创建新的对象。即拷贝原有的对象来创建新的对象,这种模式适用于创建一个复杂对象,如从庞大数据库中创建出来,在每次使用时候避免重新创建新的对象,而是直接使用旧的对象复杂出来再修改,这样的使用场景之上使得运行效率更高。
二、代码结构实现原型模式
在演示原型模式之前,先提一下深拷贝和浅拷贝的概念。如下图:
其实在C++的角度上理解还是很轻松的,就是一个指针和一块内存的问题。左边浅拷贝仅仅复制的是地址,右边深拷贝复制的是内存数据。而在java或者其他语言没有指针概念,他们的对象名称就是引用,关于拷贝地址和内存数据的事交给了后台来操作,所以他们的新学者可能理解起来有点困难,系统为他们提供一个clone的接口,底层做的就是深拷贝的过程。接下来看下原型模式的代码结构:
1、基类
就提供一个克隆方法
class CPrototype
{
public:
virtual~CPrototype(){};
virtual CPrototype*Clone()=0;
};
2、子类
实现clone方法,注意深度拷贝地方: *(cp->ch) = *(this->ch);,此处故意写的很明显
class CConcretePrototype : public CPrototype
{
public:
CConcretePrototype() :data(0), ch(0){};
~CConcretePrototype(){ delete ch; ch = 0; };
CPrototype*Clone()
{
CConcretePrototype* cp = new CConcretePrototype;
cp->data = this->data;
*(cp->ch) = *(this->ch);
return cp;
};
private:
int data;
char*ch;
};
3、客户端代码
CPrototype *instanceA = new CConcretePrototype;
//此处可以修改instace的data、ch然后执行clone,此处省略,因为设为private,没有添加更多的代码
CPrototype*instanceB = instanceA->Clone();
delete instanceA;
delete instanceB;
三、代码实现的注意事项
1、clone函数的实现,成员变量有指针的必须开辟内存,再拷贝,不能指向同一块地址
2、构造函数不需要私有化,因为允许公开生成对象
四、原型模式的使用方法
在实际开发过程中,经常会遇到这种结构,比如登录时候,要保证登录信息,如用户名、基本信息等,在其他地方如果想用这些信息的时候,可以提供一个clone版本对象给他们,他们所做的修改都不会影响登录时候的信息,直到退出系统,才更新最后的信息到配置文件。
简单模拟:
class ILogin
{
public:
virtual~ILogin(){};
virtual ILogin*Clone() = 0;
};
class ClientLogin :public ILogin
{
public:
ClientLogin():username("ali"),otherInfo("taobao"){};
ILogin*Clone()
{
ClientLogin*login = new ClientLogin;
login->username = this->username;
login->otherInfo = this->otherInfo;
return login;
}
private:
std::string username;
std::string otherInfo;
};
客户端
ILogin *instanceA = new ClientLogin;
ILogin*instanceB = instanceA->Clone();
delete instanceA;
delete instanceB;
五、优缺点
优点:创建对象较为复杂时,原型模式可以简化创建过程,提高效率;创建简单,无需另外的类创建此对象;可辅助撤销操作
缺点:改造类时,对修改的数据重新实现clone方法;当多对象时进行克隆,需要每个对象都支持深度拷贝,否则指针失效。