一 模式定义和类型
原型模式表达的是:先产生原型对象,通过原型对象产生其拷贝对象返回给调用端。
原型模式属于:对象模式和对象创建模式。
二 图
三 适用范围
当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
四 例子
如何在JAVA编程中使用原型模式?
JAVA类库为原型模式提供支持。在基类Object中定义了方法clone(),需要提供clone功能的子类可以覆盖这个方法,通过实现cloneable接口,在子类中可以调用Object的clone方法实现对象的浅拷贝(shallow copy)(如果不实现cloneable接口,在子类中调用Object的clone方法会抛出异常)。
以使用GDI+进行图片处理的程序为例,其中多个功能需要预览图片即将进行的处理(如Sharp、Darken、Rotate等)所能实现的效果,在用户没有最终确定该处理之前,需要复制一个当前Image对象的拷贝,然后对该拷贝进行处理,在创建该拷贝时存在一个问题,由于我们使用的是基类Image的指针,因此存在前面所说的问题,不能直接调用拷贝构造函数来创建新对象,同时,也不可能跟创建原型对象一样从文件流建立对象,而且,对象当前所处的状态是经过处理的,与创建之初的状态并不一样。为了便于我们解决类似这样的问题,Image类提供了一个Clone方法,以便我们进行对象的拷贝,Clone方法是虚基类Image的虚方法,由各子类具体实现。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Image
{
virtual Image* clone() = 0;
virtual void reform() { cout << "reforming Image[" << this << "]" << endl; }
};
class Bitmap : public Image
{
public:
Bitmap(const string& filename) : filename(filename) {}
Bitmap(const Bitmap& pic) : filename(pic.filename) {}
Image* clone() { return new Bitmap(*this); } // to simplify code, just call copy-ctor to create a clone
private:
string filename;
// other attributes
};
class OtherPicFormat : public Image
{
public:
OtherPicFormat(const string& filename, int otherinitialoption) :
filename(filename), otherinitialoption(otherinitialoption) {}
OtherPicFormat(const OtherPicFormat& pic) :
filename(pic.filename), otherinitialoption(pic.otherinitialoption) {}
Image* clone() { return new OtherPicFormat(*this); } // to simplify code, just call copy-ctor to create a clone
private:
string filename;
int otherinitialoption;
// other attributes
};
int main()
{
Image* ba[] = {new Bitmap("abc"), new OtherPicFormat("cde", 0)};
vector<Image*> vb;
copy(ba, ba + sizeof(ba) / sizeof(Image*), back_inserter(vb));
Image* pb = NULL;
for (vector<Image*>::iterator it = vb.begin(); it != vb.end(); ++it)
{
pb = (*it)->clone(); // clone will create a new object
pb->reform();
delete pb;
delete *it;
}
return 0;
}
五 相关的模式
Prototype模式常常被用于与Flyweight模式(利用Prototype模式构造享元对象的拷贝);
State模式(利用Prototype模式构造状态类对象的拷贝,以供在对象间传递这些状态信息);
Strategy模式与State模式下类似,利用Prototype模式构造Strategy类对象的拷贝,在不同的StrategyUser类间传递Strategy对象。
Prototype模式和工厂模式有本质区别,前者是处理根据已有的原型对象产生拷贝对象,
而工厂模式强调的是把对象创建的职责封装到特定的方法或者类中。