设计模式C++实现(1)——工厂模式

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

       工厂模式属于创建型模式,大致可以分为三类,简单工厂模式、工厂方法模式、抽象工厂模式。听上去差不多,都是工厂模式。下面一个个介绍,首先介绍简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。有点抽象,举个例子就明白了。有一家生产处理器核的厂家,它只有一个工厂,能够生产两种型号的处理器核。客户需要什么样的处理器核,一定要显示地告诉生产工厂。下面给出一种实现方案。

[cpp] view plaincopyprint?
  1. enum CTYPE {COREA, COREB};     
  2. class SingleCore    
  3. {    
  4. public:    
  5.     virtual void Show() = 0;  
  6. };    
  7. //单核A    
  8. class SingleCoreA: public SingleCore    
  9. {    
  10. public:    
  11.     void Show() { cout<<"SingleCore A"<<endl; }    
  12. };    
  13. //单核B    
  14. class SingleCoreB: public SingleCore    
  15. {    
  16. public:    
  17.     void Show() { cout<<"SingleCore B"<<endl; }    
  18. };    
  19. //唯一的工厂,可以生产两种型号的处理器核,在内部判断    
  20. class Factory    
  21. {    
  22. public:     
  23.     SingleCore* CreateSingleCore(enum CTYPE ctype)    
  24.     {    
  25.         if(ctype == COREA) //工厂内部判断    
  26.             return new SingleCoreA(); //生产核A    
  27.         else if(ctype == COREB)    
  28.             return new SingleCoreB(); //生产核B    
  29.         else    
  30.             return NULL;    
  31.     }    
  32. };    

       这样设计的主要缺点之前也提到过,就是要增加新的核类型时,就需要修改工厂类。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

       听起来很抽象,还是以刚才的例子解释。这家生产处理器核的产家赚了不少钱,于是决定再开设一个工厂专门用来生产B型号的单核,而原来的工厂专门用来生产A型号的单核。这时,客户要做的是找好工厂,比如要A型号的核,就找A工厂要;否则找B工厂要,不再需要告诉工厂具体要什么型号的处理器核了。下面给出一个实现方案。

[cpp] view plaincopyprint?
  1. class SingleCore    
  2. {    
  3. public:    
  4.     virtual void Show() = 0;  
  5. };    
  6. //单核A    
  7. class SingleCoreA: public SingleCore    
  8. {    
  9. public:    
  10.     void Show() { cout<<"SingleCore A"<<endl; }    
  11. };    
  12. //单核B    
  13. class SingleCoreB: public SingleCore    
  14. {    
  15. public:    
  16.     void Show() { cout<<"SingleCore B"<<endl; }    
  17. };    
  18. class Factory    
  19. {    
  20. public:    
  21.     virtual SingleCore* CreateSingleCore() = 0;  
  22. };    
  23. //生产A核的工厂    
  24. class FactoryA: public Factory    
  25. {    
  26. public:    
  27.     SingleCoreA* CreateSingleCore() { return new SingleCoreA; }    
  28. };    
  29. //生产B核的工厂    
  30. class FactoryB: public Factory    
  31. {    
  32. public:    
  33.     SingleCoreB* CreateSingleCore() { return new SingleCoreB; }    
  34. };    

       工厂方法模式也有缺点,每增加一种产品,就需要增加一个对象的工厂。如果这家公司发展迅速,推出了很多新的处理器核,那么就要开设相应的新工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。

       既然有了简单工厂模式和工厂方法模式,为什么还要有抽象工厂模式呢?它到底有什么作用呢?还是举这个例子,这家公司的技术不断进步,不仅可以生产单核处理器,也能生产多核处理器。现在简单工厂模式和工厂方法模式都鞭长莫及。抽象工厂模式登场了。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。具体这样应用,这家公司还是开设两个工厂,一个专门用来生产A型号的单核多核处理器,而另一个工厂专门用来生产B型号的单核多核处理器,下面给出实现的代码。

[cpp] view plaincopyprint?
  1. //单核    
  2. class SingleCore     
  3. {    
  4. public:    
  5.     virtual void Show() = 0;  
  6. };    
  7. class SingleCoreA: public SingleCore      
  8. {    
  9. public:    
  10.     void Show() { cout<<"Single Core A"<<endl; }    
  11. };    
  12. class SingleCoreB :public SingleCore    
  13. {    
  14. public:    
  15.     void Show() { cout<<"Single Core B"<<endl; }    
  16. };    
  17. //多核    
  18. class MultiCore      
  19. {    
  20. public:    
  21.     virtual void Show() = 0;  
  22. };    
  23. class MultiCoreA : public MultiCore      
  24. {    
  25. public:    
  26.     void Show() { cout<<"Multi Core A"<<endl; }    
  27.     
  28. };    
  29. class MultiCoreB : public MultiCore      
  30. {    
  31. public:    
  32.     void Show() { cout<<"Multi Core B"<<endl; }    
  33. };    
  34. //工厂    
  35. class CoreFactory      
  36. {    
  37. public:    
  38.     virtual SingleCore* CreateSingleCore() = 0;  
  39.     virtual MultiCore* CreateMultiCore() = 0;  
  40. };    
  41. //工厂A,专门用来生产A型号的处理器    
  42. class FactoryA :public CoreFactory    
  43. {    
  44. public:    
  45.     SingleCore* CreateSingleCore() { return new SingleCoreA(); }    
  46.     MultiCore* CreateMultiCore() { return new MultiCoreA(); }    
  47. };    
  48. //工厂B,专门用来生产B型号的处理器    
  49. class FactoryB : public CoreFactory    
  50. {    
  51. public:    
  52.     SingleCore* CreateSingleCore() { return new SingleCoreB(); }    
  53.     MultiCore* CreateMultiCore() { return new MultiCoreB(); }    
  54. };   

        至此,工厂模式介绍完了。利用Rational Rose 2003软件,给出三种工厂模式的UML图,加深印象。

         简单工厂模式的UML图:

         工厂方法的UML图:

         抽象工厂模式的UML图:



         本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java对象间的转型,详细讲述Java中的对象转型

向上转型&#xff1a;子类对象转为父类&#xff0c;父类可以是接口。公式&#xff1a;Father f new Son();Father是父类或接口&#xff0c;son是子类。向下转型&#xff1a;父类对象转为子类。公式&#xff1a;Son s (Son)f;我们将形参设为父类Animal类型&#xff0c;当执行t…

C++设计模式之一 工厂模式(简单工厂、工厂和抽象工厂)

今天开始这个系列之前&#xff0c;心里有些恐慌&#xff0c;毕竟园子里的高手关于设计模式的经典文章很多很多&#xff0c;特别是大侠李会军、吕震宇 老师的文章更是堪称经典。他们的文笔如行云流水&#xff0c;例子活泼生动&#xff0c;讲解深入浅出。好在他们都是用C#描述&am…

【转】Windows消息传递机制详解

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka Windows是一个消息&#xff08;Message&#xff09;驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发&#xff0c;并且靠对消…

设计模式C++实现(2)——单例模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

设计模式C++实现(3)——建造者模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

宽字符串忽略大小写比较的实现(原)

宽字符串忽略大小写比较的实现(原) 孙文涛 2008-07-24 在Mac机器平台上没有wcsicmp 或 wcscasecmp之类的函数实现对宽字符忽略大小写的比较&#xff0c;所以实现了好几种方法。 一个自然的思路是: (1) wcscpy 原字符串到tmp字符串; (2) tolower tmp字符串; (3) 然后调用仅存的w…

有关JAVA考试中数据库的题,javaee期末考试题库,用javaEE编写一个题库系统,要怎么做...

javaEE数据库简单问题。你插入2113数据库的时候是把5261它封装为一4102个对象插入的吗&#xff1f;1653如果封装为一个User对象版的权话(User对象有ID和LEVEL两个属性)ResultSet rs ps.executeQuery();User user new User();if(rs.hasNext()){user rs.next();}关于javaee 中j…

oracle 12c sql图形化,Oracle 12c PL/SQL程序设计终极指南

Oracle 12c PL/SQL程序设计终极指南作者&#xff1a;孙风栋;王澜;郭晓惠出版日期&#xff1a;2015年06月文件大小&#xff1a;11.73M支持设备&#xff1a;&#xffe5;60.00在线试读适用客户端&#xff1a;言商书局iPad/iPhone客户端&#xff1a;下载 Android客户端&#xff1a…

oracle 存储同步,Oracle数据库知识——存储过程篇

在线QQ客服&#xff1a;1922638专业的SQL Server、MySQL数据库同步软件存储过程是一组用于完成特定功能的SQL语句&#xff0c;该语句已编译并存储在数据库中。用户通过指定存储过程的名称并提供参数(如果存储过程具有参数)来执行它。存储过程是数据库中的重要对象。任何设计良好…

使用MvcContrib的FormHelper

MvcContrib的FormHelper提供了三大Helper Html辅助 验证HelperGrid表格Helper下载 下载后将MvcContrib.dll与MvcContrib.Samples.FormHelper.dll引用到Asp.net MVC工程 在Web.Config pages.namespaces加入以下节点 <add namespace"MvcContrib.UI.Tags"/><ad…

WinCE控制面板添加应用程序

WinCE系统中的控制面板和Windows系统中的控制面板原理是一样的&#xff0c;里面就是包含了一些应用程序。WinCE系统的控制面板由Ctlpnl.exe&#xff0c;Control.exe和一些.cpl文件组成&#xff0c;其中Ctlpnl.exe和Control.exe用于控制控制面板的文件夹显示和架构&#xff0c;而…

oracle 游标 904,如何解决Oracle数据库游标连接超出问题

如何解决Oracle数据库游标连接超出问题发布时间&#xff1a;2020-07-21 10:57:35来源&#xff1a;亿速云阅读&#xff1a;103作者&#xff1a;小猪这篇文章主要讲解了如何解决Oracle数据库游标连接超出问题&#xff0c;内容清晰明了&#xff0c;对此有兴趣的小伙伴可以学习一下…

用多媒体库 Bass.dll 播放 mp3 [15] - 设置与获取播放速度

本例效果图:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;typeTForm1 class(TForm)OpenDialog1: TOpenDialog;Button1: TButton;Button2: TButton;Button3: TButton;TrackBar1:…

【转】Dicom文件解析!!!!!!

转自&#xff1a;https://blog.csdn.net/leaf6094189/article/details/8510325 Dicom全称是医学数字图像与通讯&#xff0c;这里讲的暂不涉及通讯那方面的问题 只讲*.dcm 也就是diocm格式文件的读取&#xff0c;读取本身是没啥难度的 无非就是字节码数据流处理。只不过确实比较…

VS2008 JS脚本调试总是调试旧代码 真不知道怎么回事?谁能帮帮我呀!

如图,[dynamic]标记的是调试的元文件 xml1.htm[dynamic]和xml.js[dynamic] 我更改后的文件是xml1.htm和xml.js,见图1 2 调试的文件有debugger 更改后的文件我把debugger注了 js脚本中我把变量给改了见3 4 ,所以在浏览新的xml1.htm时,竟然报对象找不到,真实受不了了!!! 为什么我…

【转】C#开发PACS医学影像处理系统(一):开发背景和功能预览

转自&#xff1a;https://www.cnblogs.com/Uncle-Joker/p/13646949.html 本系列文章将从以下模块和大家分享和讨论使用C#开发医学软件PACS和RIS系统&#xff0c; 国内相关资料比较少&#xff0c;也借此机会丰富一下医学软件开发生态&#xff0c;讨论技术难点&#xff0c;希望…

《WF编程》系列之30 - 基本活动:错误处理

《WF编程》系列之30 - 基本活动:错误处理 4.3 错误处理 Fault,故障,现在官方已经将其翻译为错误,那么以后的随笔中我也就采用官方的翻译吧. 错误处理也属于流程控制的一部分,这一节我来介绍一下有关错误处理的活动.错误是指在工作流执行期间发生的异常.我们可以使用错误处理程…

oracle错误27101,ORA-27101ORA-01034错误解决

Oracle已经启动&#xff0c;连接sqlplus后&#xff0c;进行查询&#xff0c;出现下面错误ORA-01034: ORACLE not availableORA-27101: shared memory realm doesOracle已经启动&#xff0c;连接sqlplus后&#xff0c;进行查询&#xff0c;出现下面错误ORA-01034: ORACLE not av…

NOD32升级ID获取器For流星无语更新了

NOD32升级ID获取器For流星无语更新了一下,现在可以直接把用户名密码写入注册表了,连复制/粘贴操作都可以免了...转载于:https://www.cnblogs.com/lxwy/archive/2008/09/05/4420722.html

【转】【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件

转自&#xff1a;https://developer.aliyun.com/article/672065 最近研究了一下DICOM和BMP文件转换的问题&#xff0c;也是很头大。度娘了很久&#xff0c;也在CSDN等论坛看到一些断断续续的文件&#xff0c;最主要的是代码只是片断&#xff0c;不是完整的实现。头大了。 首先…