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

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

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

[cpp] view plaincopy print?
  1. //父类
  2. class Resume
  3. {
  4. protected:
  5. char *name;
  6. public:
  7. Resume() {}
  8. virtual ~Resume() {}
  9. virtual Resume* Clone() { return NULL; }
  10. virtual void Set(char *n) {}
  11. virtual void Show() {}
  12. };
[cpp] view plaincopy print?
  1. class ResumeA : public Resume
  2. {
  3. public:
  4. ResumeA(const char *str);  //构造函数
  5. ResumeA(const ResumeA &r); //拷贝构造函数
  6. ~ResumeA();                //析构函数
  7. ResumeA* Clone();          //克隆,关键所在
  8. void Show();               //显示内容
  9. };
  10. ResumeA::ResumeA(const char *str)
  11. {
  12. if(str == NULL) {
  13. name = new char[1];
  14. name[0] = '\0';
  15. }
  16. else {
  17. name = new char[strlen(str)+1];
  18. strcpy(name, str);
  19. }
  20. }
  21. ResumeA::~ResumeA() { delete [] name;}
  22. ResumeA::ResumeA(const ResumeA &r) {
  23. name = new char[strlen(r.name)+1];
  24. strcpy(name, r.name);
  25. }
  26. ResumeA* ResumeA::Clone() {
  27. return new ResumeA(*this);
  28. }
  29. void ResumeA::Show() {
  30. cout<<"ResumeA name : "<<name<<endl;
  31. }

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

[cpp] view plaincopy print?
  1. int main()
  2. {
  3. Resume *r1 = new ResumeA("A");
  4. Resume *r2 = new ResumeB("B");
  5. Resume *r3 = r1->Clone();
  6. Resume *r4 = r2->Clone();
  7. r1->Show(); r2->Show();
  8. //删除r1,r2
  9. delete r1; delete r2;
  10. r1 = r2 = NULL;
  11. //深拷贝所以对r3,r4无影响
  12. r3->Show(); r4->Show();
  13. delete r3; delete r4;
  14. r3 = r4 = NULL;
  15. }

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

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

[cpp] view plaincopy print?
  1. //简历
  2. class Resume
  3. {
  4. protected: //保护成员
  5. virtual void SetPersonalInfo() {}
  6. virtual void SetEducation() {}
  7. virtual void SetWorkExp() {}
  8. public:
  9. void FillResume()
  10. {
  11. SetPersonalInfo();
  12. SetEducation();
  13. SetWorkExp();
  14. }
  15. };
  16. class ResumeA: public Resume
  17. {
  18. protected:
  19. void SetPersonalInfo() { cout<<"A's PersonalInfo"<<endl; }
  20. void SetEducation() { cout<<"A's Education"<<endl; }
  21. void SetWorkExp() { cout<<"A's Work Experience"<<endl; }
  22. };
  23. class ResumeB: public Resume
  24. {
  25. protected:
  26. void SetPersonalInfo() { cout<<"B's PersonalInfo"<<endl; }
  27. void SetEducation() { cout<<"B's Education"<<endl; }
  28. void SetWorkExp() { cout<<"B's Work Experience"<<endl; }
  29. };

使用方式如下:

[cpp] view plaincopy print?
  1. int main()
  2. {
  3. Resume *r1;
  4. r1 = new ResumeA();
  5. r1->FillResume();
  6. delete r1;
  7. r1 = new ResumeB();
  8. r1->FillResume();
  9. delete r1;
  10. r1 = NULL;
  11. return 0;
  12. }

设计模式C++实现(5)——原型模式、模板方法模式相关推荐

  1. 【设计模式】第十三章:模板方法模式详解及应用案例

    系列文章 [设计模式]七大设计原则 [设计模式]第一章:单例模式 [设计模式]第二章:工厂模式 [设计模式]第三章:建造者模式 [设计模式]第四章:原型模式 [设计模式]第五章:适配器模式 [设计模式 ...

  2. 设计模式 — 行为型模式 — 模板方法模式

    目录 文章目录 目录 模板方法模式 应用场景 代码示例 模板方法模式 模板方法模式,定义一个算法或者流程,部分环节设计为外部可变,用类似于模板的思想来实例化一个实体,可以往模板中填充不同的内容: 在模 ...

  3. Java设计模式(代理模式-模板方法模式-命令模式)

    Java设计模式Ⅴ 1.代理模式 1.1 代理模式概述 1.2 静态代理 1.2.1 静态代理概述 1.2.2 代码理解 1.3 动态代理之JDK代理 1.3.1 动态代理之JDK代理概述 1.3.2 ...

  4. Head First设计模式读书笔记七 第八章 模板方法模式

    本文示例代码材料源自Head First设计模式 以前整理自己整理的链接: https://blog.csdn.net/u011109881/article/details/60594985 简介 模 ...

  5. 《设计模式详解》行为型模式 - 模板方法模式

    模板方法模式 6.1 模板方法模式 6.1.1 概述 6.1.2 结构 6.1.3 案例实现 6.1.3 优缺点 6.1.4 适用场景 6.1.5 JDK源码 - InputStream 完整的笔记目 ...

  6. 李建忠设计模式-组件协作模式-模板方法模式

    目录 1.前言 2.模板方法模式(Template Method) 1.动机 2.例子 3.定义 1.结构图 2.模板方法模式适用情形 3.模式特点 参考 1.前言 现代软件专业分工后的第一个结果是& ...

  7. 设计模式学习(十六) 模板方法模式

    场景: -- 客户到银行办理业务 1:取号排队 2:办理具体现金/转账/企业/个人/理财业务 3: 给银行工作人员评分 模板方法介绍; -- 模板方法模式是编程中经常用到的模式,它定义了一个操作中的算 ...

  8. java设计模式-- 观察者模式 , 外观模式, 模板方法模式

    观察者模式: 观察者模式比较容易理解: 比如天龙八部里面的王语嫣,每次慕容复打架的时候,每当别人将要使出什么绝招时,会提醒慕容复注意提防. 项目中用到的地方就是注册中中心,zookeeper,当Pro ...

  9. 聊聊那些专为算法设计的模式——模板方法模式

    AI越来越火热,人工智能已然成风!而人工智能最重要是各种算法,因此机器学习越来越受到追捧,算法越来越被重视. 作为一个算法的研究者,写出一手高级算法当然是令人兴奋的一件事!但你是否有时会有这种感觉: ...

  10. 行为型模式-模板方法模式

    1.概述 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关. ...

最新文章

  1. kf真空接头标准尺寸_酒泉VER8314KN39H出口过滤器滤芯 高线真空滤油机介
  2. div居中与div内容居中,不一样
  3. 时间序列分类算法简介及其在能耗数据分类上的应用
  4. LeetCode 778. 水位上升的泳池中游泳(二分查找+dfs)
  5. 【Codeforces 1096D】Easy Problem
  6. android手机游戏开发从入门到精通_unity3d游戏开发如何从入门到精通?
  7. mysql执行ref_MySql执行分析
  8. 如何在Node.js中处理POST数据?
  9. httpsession 是一样的吗_理解HTTP session原理及应用
  10. ANDROID框架揭秘
  11. FTP成功连接服务器后,出现乱码问题
  12. Thinkphp中的 I 函数(Thinkphp3.2.3版本)
  13. 物联网数据多又杂?好用的数据可视化服务来了
  14. Codeforces Round #469 (Div. 2) C. Zebras
  15. MMR 算法信息收集
  16. PM2 自动化部署项目 之 (Vue SSR)
  17. Python-七段数码管的绘制
  18. Python 多线程、利用request使用代理、利用递归深度抓取电影网页的内容并将电影的介绍和下载链接保存到mysql中
  19. 数据库中的三级范式(1NF、2NF、3NF、BCNF)
  20. mac 修改无扩展名文件的默认打开方式

热门文章

  1. CNN之性能指标:卷积神经网络中常用的性能指标(IOU/AP/mAP、混淆矩阵)简介、使用方法之详细攻略
  2. Dataset之RentListingInquries:RentListingInquries(Kaggle竞赛)数据集的简介、下载、案例应用之详细攻略
  3. Python机器学习类库常见问题及解决
  4. Ubuntu16.04 Docker 安装
  5. Android插件化开发之解决OpenAtlas组件在宿主的注冊问题
  6. jquery.cookies使用
  7. Mathematica数据处理(11)--标签
  8. Ganglia的配置,用于监测系统和Hadoop性能
  9. hiberante 二级缓存设置
  10. Windows MObile中ListView控件的用法详解