创建型模式
使用环境:
- 创建新对象成本较大,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改
- 系统要保存对象的状态,而对象的状态变化很小
- 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。
模式优点:
- 简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率
- 扩展性较好
- 提供了简化的创建结构,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品
- 可以使用深克隆的方式保存对象的状态,以便在需要的时候使用,可辅助实现撤销操作
模式缺点:
- 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造,需要修改源代码,违背了开闭原则
- 在实现神克隆时需要编写较为复杂的代码,而且当对象之间存在多重的嵌套引用时,为了实现深克隆,没一层对象对应的类都必须支持深克隆,实现起来可能会比较麻烦
类图:
浅克隆和深克隆:
- 浅克隆:(shallow Clone)当原型对象被复制时,之复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制
- 深克隆:(Deep Clone)除了对象本身被复制外,对象所包含的所有成员变量也将被复制
- 个人总结:从C++角度而言,浅克隆是复制了地址,深克隆是对值进行拷贝。换言之,浅克隆只是复制了一个镜像,而深克隆是创建了另一个新的对象。
代码:
#include <iostream>
using namespace std;
class Prototype{
public:
virtual Prototype* Clone() = 0;
Prototype(){ cout << "This is Prototype" << endl;}
virtual ~Prototype(){ cout << "Delete Prototype" << endl;}
};
class ConcretePrototypeA:public Prototype{
public:
ConcretePrototypeA(){ cout << "This is ConcretePrototypeA" << endl;}
~ConcretePrototypeA(){ cout << "Delete ConcretePrototypeA" << endl;}
ConcretePrototypeA(const ConcretePrototypeA&);
Prototype* Clone();
};
ConcretePrototypeA::ConcretePrototypeA(const ConcretePrototypeA &) {
cout << "This is ConcretePrototypeA copy" << endl;
}
Prototype* ConcretePrototypeA::Clone() {
cout << "This is Clone in A" << endl;
return new ConcretePrototypeA(*this);
}
class ConcretePrototypeB:public Prototype{
public:
ConcretePrototypeB(){ cout << "This is ConcretePrototypeB" << endl;}
~ConcretePrototypeB(){ cout << "Delete ConcretePrototypeB" << endl;}
ConcretePrototypeB(const ConcretePrototypeB&);
Prototype* Clone();
};
ConcretePrototypeB::ConcretePrototypeB(const ConcretePrototypeB &) {
cout << "This is ConcretePrototypeB copy" << endl;
}
Prototype* ConcretePrototypeB::Clone() {
cout << "This is Clone in B" << endl;
return new ConcretePrototypeB(*this);
}
int main(){
Prototype *p1 = new ConcretePrototypeA();
Prototype *p2 = p1->Clone();
cout << "--------------------------------------------" << endl;
Prototype *p3 = new ConcretePrototypeB();
Prototype *p4 = p3->Clone();
cout << "--------------------------------------------" << endl;
delete p1;
delete p2;
delete p3;
delete p4;
return 0;
}
运行结果:
This is Prototype
This is ConcretePrototypeA
This is Clone in A
This is Prototype
This is ConcretePrototypeA copy
--------------------------------------------
This is Prototype
This is ConcretePrototypeB
This is Clone in B
This is Prototype
This is ConcretePrototypeB copy
--------------------------------------------
Delete ConcretePrototypeA
Delete Prototype
Delete ConcretePrototypeA
Delete Prototype
Delete ConcretePrototypeB
Delete Prototype
Delete ConcretePrototypeB
Delete Prototype