博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式C++实现(5)——原型模式、模板方法模式
阅读量:6454 次
发布时间:2019-06-23

本文共 2545 字,大约阅读时间需要 8 分钟。

hot3.png

  软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计 模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计 模式》和《设计模式:可复用面向对象软件的基础》(DP)两本书。本文介绍原型模式和模板方法模式的实现。首先介绍原型模式,然后引出模板方法模式。

       DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。其中有一个词很重要,那就是拷贝。可以说,拷贝是原型模式的精髓 所在。举个现实中的例子来介绍原型模式。找工作的时候,我们需要准备简历。假设没有打印设备,因此需手写简历,这些简历的内容都是一样的。这样有个缺陷, 如果要修改简历中的某项,那么所有已写好的简历都要修改,工作量很大。随着科技的进步,出现了打印设备。我们只需手写一份,然后利用打印设备复印多份即 可。如果要修改简历中的某项,那么修改原始的版本就可以了,然后再复印。原始的那份手写稿相当于是一个原型,有了它,就可以通过复印(拷贝)创造出更多的 新简历。这就是原型模式的基本思想。下面给出原型模式的UML图,以刚才那个例子为实例。

        原型模式实现的关键就是实现Clone函数,对于C++来说,其实就是拷贝构造函数,需实现深拷贝,下面给出一种实现。

//父类class Resume{protected:	char *name;public:	Resume() {}	virtual ~Resume() {}	virtual Resume* Clone() { return NULL; }	virtual void Set(char *n) {}	virtual void Show() {}};
class ResumeA : public Resume{public:	ResumeA(const char *str);  //构造函数	ResumeA(const ResumeA &r); //拷贝构造函数	~ResumeA();                //析构函数	ResumeA* Clone();          //克隆,关键所在	void Show();               //显示内容};ResumeA::ResumeA(const char *str) {	if(str == NULL) {		name = new char[1]; 		name[0] = '\0'; 	}	else {		name = new char[strlen(str)+1];		strcpy(name, str);	}}ResumeA::~ResumeA() { delete [] name;}ResumeA::ResumeA(const ResumeA &r) {	name = new char[strlen(r.name)+1];	strcpy(name, r.name);}ResumeA* ResumeA::Clone() {	return new ResumeA(*this);}void ResumeA::Show() {	cout<<"ResumeA name : "<
<

          这里只给出了ResumeA的实现,ResumeB的实现类似。使用的方式如下:

int main(){	Resume *r1 = new ResumeA("A");	Resume *r2 = new ResumeB("B");	Resume *r3 = r1->Clone();	Resume *r4 = r2->Clone();	r1->Show(); r2->Show();	//删除r1,r2	delete r1; delete r2;		r1 = r2 = NULL;	//深拷贝所以对r3,r4无影响	r3->Show(); r4->Show();	delete r3; delete r4;	r3 = r4 = NULL;}

       最近有个招聘会,可以带上简历去应聘了。但是,其中有一家公司不接受简历,而是给应聘者发了一张简历表,上面有基本信息、教育背景、工作经历等栏,让应 聘者按照要求填写完整。每个人拿到这份表格后,就开始填写。如果用程序实现这个过程,该如何做呢?一种方案就是用模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。我们的例子中,操作就是填写简历这一过程,我们可以在父类中定义操作的算法骨架,而具体的实现由子类完成。下面给出它的UML图。

       其中FillResume() 定义了操作的骨架,依次调用子类实现的函数。相当于每个人填写简历的实际过程。接着给出相应的C++代码。

//简历class Resume{protected: //保护成员	virtual void SetPersonalInfo() {}	virtual void SetEducation() {}	virtual void SetWorkExp() {}public:	void FillResume() 	{		SetPersonalInfo();		SetEducation();		SetWorkExp();	}};class ResumeA: public Resume{protected:	void SetPersonalInfo() { cout<<"A's PersonalInfo"<

        使用方式如下:

int main(){	Resume *r1;	r1 = new ResumeA();	r1->FillResume();	delete r1;	r1 = new ResumeB();	r1->FillResume();	delete r1;	r1 = NULL;	return 0;}

转载于:https://my.oschina.net/iamhere/blog/417586

你可能感兴趣的文章
简单的导出表格和将表格下载到桌面上。
查看>>
《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
查看>>
递归查询上一级
查看>>
JAVA - 大数类详解
查看>>
查询指定名称的文件
查看>>
Python 嵌套列表解析
查看>>
[GXOI/GZOI2019]旧词——树链剖分+线段树
查看>>
android 补间动画的实现
查看>>
2017年广东省ACM省赛(GDCPC-2017)总结
查看>>
第十届蓝桥杯B组C++题目详解和题型总结
查看>>
简单理解函数回调——同步回调与异步回调
查看>>
Android 多个Activity 跳转及传参
查看>>
anroid 广播
查看>>
AJAX POST&跨域 解决方案 - CORS
查看>>
关于最小生成树中的kruskal算法中判断两个点是否在同一个连通分量的方法总结...
查看>>
开篇,博客的申请理由
查看>>
点滴积累【C#】---C#实现上传word以流形式保存到数据库和读取数据库中的word文件。...
查看>>
Ubuntu常用笔记
查看>>
Token和session 详解
查看>>
JMeter IP欺骗压测
查看>>