1、意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建对象。
2、适用性
当一个系统应用独立于它的产品创建、构成和表示时,要使用Prototype模式
(1)当要实例化的类是在运行时刻指定时
(2)为了避免创建一个与产品类层次平行的工厂类层次时
(3)当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
3、结构
5、参与者
Prototype:声明一个克隆自身的接口
ConcretePrototype:实现克隆自身的操作
Client:让一个原型克隆自身从而创建一个对象
6、效果
优点
(1)运行时刻增加和删除产品
(2)改变值以指定新对象
(3)改变结构以指定新对象
(4)减少子类的创建
缺点:每一个Prototype的子类都必须实现clone操作,这可能很困难。例如,当所考虑的类已经存在时就难以新增clone操作。当内部包括一些不支持拷贝或有循环引用的对象时,实现克隆可能也会很困难的。
7、相关模式
Prototype和Abstract Factory模式在某种方面是相互竞争的。但是它们也可以一起使用。Abstract Factory可以存储一个被克隆的原型的集合,并且返回产品对象。
大量使用Composite和Decorator模式的设计通常也可从Prototype模式处获益。
C++代码如下
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class Prototype
{
public:
virtual unique_ptr<Prototype> clone() = 0;
};
class ConcretePrototype1 : public Prototype
{
string name;
public:
ConcretePrototype1(const ConcretePrototype1 &t) { *this = t;};
ConcretePrototype1& operator = (const ConcretePrototype1 &t)
{
name = t.name;
return *this;
}
ConcretePrototype1(const string &s) : name(s) {}
void setName(const string &s) {name = s;};
string getName() {return name;}
unique_ptr<Prototype> clone()
{
unique_ptr<Prototype> copy(new ConcretePrototype1(*this));
return copy;
}
};
class ConcretePrototype2 : public Prototype
{
int value;
public:
ConcretePrototype2(const int &v) : value(v) {}
void setValue(int v) {value = v;}
int getValue() {return value;}
unique_ptr<Prototype> clone()
{
unique_ptr<Prototype> copy(new ConcretePrototype2(*this));
return copy;
}
};
int main()
{
ConcretePrototype1 a("prototype design pattern");
ConcretePrototype2 b(7);
unique_ptr<Prototype> aCpy = a.clone();
unique_ptr<Prototype> bCpy = b.clone();
ConcretePrototype1 *pa = dynamic_cast<ConcretePrototype1*>(aCpy.get());
ConcretePrototype2 *pb = dynamic_cast<ConcretePrototype2*>(bCpy.get());
pa->setName("abc");
pb->setValue(111);
cout << pa->getName() << endl;
cout << pb->getValue() << endl;
return 0;
}