原型(prototype)模式和工厂方法模式很像,也是为了在对象创建的时候更加灵活。但是,不同的地方是,原型模式是工厂和相应类对象的结合体,通过在类中定义一个clone方法用来克隆自己,这样的类也被称为原型。对比工厂方法,可以想到有这样的好处,省略了工厂类的定义实现,简化了创建实例的过程,因为只要复制构造就行了。当然,缺点也是有的,把clone的职责给了原型类,实际上也是增加了类的职责,
意图:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
通过已有对象来创建新的对象是它的特点
结构图:
改写工厂方法模式:
class AbProduct { public: virtual void sayName()=0; AbProduct(string name) :_name(name){} virtual ~AbProduct(){} virtual AbProduct *clone()=0; protected: string _name; }; class DBProduct:public AbProduct { public: DBProduct(string name) :AbProduct(name){} DBProduct(const DBProduct &product) :AbProduct(product._name){} ~DBProduct(){} void sayName(); virtual AbProduct *clone(); private: }; AbProduct * DBProduct::clone() { return new DBProduct(*this); } void DBProduct::sayName() { cout << _name << endl; } class TextProduct:public AbProduct { public: TextProduct(string name) :AbProduct(name){} TextProduct(const TextProduct &product) :AbProduct(product._name){} ~TextProduct(){} void sayName(); virtual AbProduct *clone(); private: }; AbProduct * TextProduct::clone() { return new TextProduct(*this); } void TextProduct::sayName() { cout << _name << endl; }
具体的用处:
class BigClient { AbProduct *_prototype; public: BigClient(AbProduct * prototype) :_prototype(prototype){} ~BigClient(){ delete _prototype; } void operation() { AbProduct *p = _prototype->clone(); p->sayName(); delete p; } };
结果:
在BigClient中,第一次创建传入的对象将作为以后的clone原型。