设计模式(4) - Prototype原型模式
2013-12-22 00:05
330 查看
1. 意图
原型模式可以让我们在创建新的实例时,隐藏内部复杂性。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C++中通过拷贝构造函数实现。
2. UML类图
3. 代码实现
#include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; const int N = 4; // Prototype class Document { public: virtual Document* clone() const = 0; virtual void store() const = 0; virtual ~Document() { } }; // Concrete prototype : xmlDoc, plainDoc, spreadsheetDoc class xmlDoc : public Document { public: Document* clone() const { return new xmlDoc; } void store() const { cout<<"xmlDoc"<<endl; } public: xmlDoc() { cout<<"xmlDoc constructor"<<endl;} ~xmlDoc() { cout<<"xmlDoc destructor"<<endl;} }; class plainDoc : public Document { public: Document* clone() const { return new plainDoc; } void store() const { cout<<"plainDoc"<<endl; } public: plainDoc() { cout<<"plainDoc constructor"<<endl;} ~plainDoc() { cout<<"plainDoc destructor"<<endl;} }; class spreadsheetDoc : public Document { public: Document* clone() const { return new spreadsheetDoc; } void store() const { cout<<"spreadsheetDoc"<<endl; } public: spreadsheetDoc() { cout<<"spreadsheetDoc constructor"<<endl;} ~spreadsheetDoc() { cout<<"spreadsheetDoc destructor"<<endl;} }; // generateDocument() calls Concrete Prototype's clone() method // inherited from base class Prototype class DocumentManager { public: static Document* generateDocument(int choice); DocumentManager() { cout<<"DocumentManager constructor"<<endl; } ~DocumentManager() { cout<<"DocumentManager destructor"<<endl; } private: static Document* _docTypes ; }; Document* DocumentManager::_docTypes[] = {0, new xmlDoc, new plainDoc, new spreadsheetDoc}; Document* DocumentManager::generateDocument(int choice) { return _docTypes[choice]->clone(); } //for_each op() class DestructClasses { public: void operator()(Document *doc) const { delete doc; } public: DestructClasses() { cout<<"DestructClasses constructor"<<endl; } ~DestructClasses() { cout<<"DestructClasses destructor"<<endl; } }; //client int main() { std::vector<Document*> docs(N); int choice=0; cout<<"quit(0), xml(1), plain(2), spreadsheet(3): "<<endl; while(true) { cout<<"Type in your choice (0-3)"<<endl; cin>>choice; if(choice<=0 || choice>=N) break; docs[choice] = DocumentManager::generateDocument(choice); } cout<<"\nvector elements print"<<endl; for(int i=0; i<docs.size(); ++i) if(NULL!=docs[i]) docs[i]->store(); cout<<endl; DestructClasses dc; for_each(docs.begin(), docs.end(), dc); system("pause"); return 0; }运行结果为:
xmlDoc constructor plainDoc constructor spreadsheetDoc constructor quit(0), xml(1), plain(2), spreadsheet(3): Type in your choice (0-3) 1 xmlDoc constructor Type in your choice (0-3) 2 plainDoc constructor Type in your choice (0-3) 3 spreadsheetDoc constructor Type in your choice (0-3) 0 vector elements print xmlDoc plainDoc spreadsheetDoc DestructClasses constructor xmlDoc destructor plainDoc destructor spreadsheetDoc destructor DestructClasses destructor DestructClasses destructor Press any key to continue . . . DestructClasses destructor由上面结果可知:
1). 3个原始对象定义为静态对象,在数组_docTypes中生成。
2).创建新的对象在clone函数中完成。注意:每种类型只能输入一次,会保存在vector中,会被析构。但是如果输入多次相同类型的值,会new出来多个对象,并且只会析构最后new出来的那个对象,前面的对象没有析构,会有内存泄漏。
3).本文重点在于说明Prototype模式,而不再于新对象的生成方式方法。
4).第26,27行是在for_each中的析构调用,第29行,是在程序退出之前,系统回收局部变量dc的内存,因而调用了其析构函数。
4. 总结
Prototype模式和Builder模式、AbstractFactory模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),它们之间的区别是:Builder模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory模式重在产生多个相互依赖类的对象,而Prototype模式重在从自身复制自己创建新类。相关文章推荐
- TPTP 资料记录
- 小经典理解
- 内存管理
- 设计模式(3) - Builder建造者模式
- 《人件》读书笔记
- Android实现启用GPRS/3G网络
- .bss .data .text 区别
- 十五章
- java 类加载器
- 关于 resgen.exe已退出 代码为 2 的错误问题的解决办法。
- Shadow学习笔记(PSM,LiSPSM,TSM,PSSM,CSM)
- WCDMA基本概念
- php安装xdebug/php安装pear/phpunit详解步骤(图)
- 在线一元二次方程计算器实例(方程计算器在线计算)
- JS中的异常处理方法分享
- 开启bin-log日志mysql报错的解决方法
- mysql服务无法启动报错误1067解决方法(mysql启动错误1067 )
- Hadoop 中 MapReduce 新旧改变
- 使用Sass创建弹性网格
- 组织Sass文件