Published by orzz.org(). (http://orzz.org/c%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f%e4%b9%8bprototype%e5%8e%9f%e5%9e%8b%e6%a8%a1%e5%bc%8f/)
当我们需要创建一种类型的对象时,可以用工厂模式;当对象的局部容易发生变化时,我们有建造者模式.但当我们有大量的对象类型,或者对象类型不易知道时,我们如何根据已有的一个对象快速构建新的对象呢?
我们需要一个可以封装掉不同种类对象之间的区别,仅伸出相同的克隆接口,让所有的对象只需要考虑自身的复制.这样我们就可以快速得到大量相同类型的对象了.
具有这种特征的模式是原型模式.其类图如下:
下面给出原型模式的C++示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
////////////////////////////////////////////////////////////////// // 原型模式 C++示例 // // Author: 木头云 // Blog: http://darkc.at // E-Mail: memleak@darkc.at // Version: 1.0.818.1720(2009/08/18) ////////////////////////////////////////////////////////////////// #include "stdafx.h" ////////////////////////////////////////////////////////////////// // 原型类 class IPrototype abstract { public: virtual ~IPrototype() { } public: virtual TSmartPtr<IPrototype> Clone() = 0; }; // 具体的原型类 class CConcretePrototype : public IPrototype { protected: _tstring str_id; _tstring str_cn; public: CConcretePrototype() : str_id(_T("")) , str_cn(_T("")) { } CConcretePrototype(const _tstring& id, const _tstring& cn) : str_id(id) , str_cn(cn) { } CConcretePrototype(const TSmartPtr<CConcretePrototype>& prototype) : str_id( prototype->str_id ) , str_cn( prototype->str_cn ) { } public: virtual TSmartPtr<IPrototype> Clone() { TSmartPtr<CConcretePrototype> prototype = new CConcretePrototype; // 拷贝数据 prototype->str_id = this->str_id; prototype->str_cn = this->str_cn; return prototype; } void SetID(const _tstring& id) { str_id = id; } _tstring GetID() { return str_id; } void SetContent(const _tstring& cn) { str_cn = cn; } _tstring GetContent() { return str_cn; } void Display() { _tcout << this->str_id << _T(": ") << this->str_cn << endl; } }; ////////////////////////////////////////////////////////////////// // 主函数 int _tmain(int argc, _TCHAR* argv[]) { CConcretePrototype p1(_T("1"), _T("第1个原型")); CConcretePrototype p2 = p1.Clone(); p2.SetContent(_T("第2个原型")); CConcretePrototype p3 = p1.Clone(); p3.SetContent(_T("第3个原型")); p1.Display(); // 显示第1个原型 p2.Display(); // 显示第2个原型 p3.Display(); // 显示第3个原型 return 0; } ////////////////////////////////////////////////////////////////// /* Prototype模式同工厂模式,同样对客户隐藏了对象的创建工作. 但是,与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的, 达到了"隔离类对象的使用者和具体类型(易变类)之间的耦合关系"的目的. */ ////////////////////////////////////////////////////////////////// |
代码运行结果如下:
1 2 3 4 |
1: 第1个原型 1: 第2个原型 1: 第3个原型 请按任意键继续. . . |
原型模式可以很方便的快速构建相同类型的对象.其构造过程有点类似细胞分裂.通过原型模式的克隆接口克隆对象,我们可以完全不关心待克隆对象本身的类型,只需要调用接口就可以产生一个新的同类对象.