简单工厂模式

2023-11-19

简单工厂模式

一,概念

        从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

二,实例

        请用C++、Java、C#任意一种面向对象语言实现一个计算器控制台程序


三,菜鸟实现

[html]  view plain copy
  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     try{  
  9.           
  10.         string a,b;  
  11.         char op;  
  12.         int result;   
  13.         cout<<"请输入数字A"<<endl;  
  14.         cin>>a;  
  15.         cout<<"请输入运算符(+,-,*,/)"<<endl;  
  16.         cin>>op;  
  17.         cout<<"请输入数字B"<<endl;  
  18.         cin>>b;  
  19.         int A=atoi(a.c_str());  
  20.         int B=atoi(b.c_str());  
  21.           
  22.         switch(op)  
  23.         {  
  24.             case '+':result=A+B;break;  
  25.             case '-':result=A-B;break;  
  26.             case '*':result=A*B;break;  
  27.             case '/':  
  28.                    if(B==0)  
  29.                       result=-9999;  
  30.                    else   
  31.                       result=A/B;  
  32.                       break;   
  33.             default:result =-9999;  
  34.         }     
  35.           
  36.         cout<<"result="<<result<<endl;  
  37.     }  
  38.     catch(exception &e)  
  39.     {  
  40.         cout<<"Exception:"<<e.what()<<endl;     
  41.     }  
  42.       
  43.     return 0;  
  44. }  



分析:程序实现还算可以,注意到了: 1)除数为0的判断,和异常的检查

                                                                     2)switch的应用,在C/C++中switch之接受 char 和 int 类型。其他的类型只能用if


存在的问题: 1)首先没有按照面向对象的设计方式实现。

                         2)不容易维护

                         3)不容易复用:控制台改成图形界面?只能复制代码,然后更改代码。不能直接调用代码类

                         4)不容易扩展:如果要添加 sqrt( ) 开方?如何实现?

                         5)灵活性不好:操作类和界面类没有分开。

解决办法:通过面向对象的三大技术封装、继承和多态


首先应用封装,让业务逻辑、界面逻辑分开,降低耦合度。

菜鸟进阶一:

[html]  view plain copy
  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5. class Operation  
  6. {  
  7. public:  
  8.  static int GetResult(int A,int B,char op) //static 静态类,所有对象共享一个方法   
  9. {  
  10.     int result;  
  11.     switch(op)  
  12.         {  
  13.             case '+':result=A+B;break;  
  14.             case '-':result=A-B;break;  
  15.             case '*':result=A*B;break;  
  16.             case '/':  
  17.                    if(B==0)  
  18.                       result=-9999;  
  19.                    else   
  20.                       result=A/B;  
  21.                       break;   
  22.             default:result =-9999;  
  23.         }     
  24.           
  25.     return result;  
  26. }  
  27.       
  28. } ;  
  29.   
  30. int main()  
  31. {  
  32.     Operation  operation;  
  33.     try{  
  34.           
  35.         string a,b;  
  36.         char op;  
  37.         int result;   
  38.         cout<<"请输入数字A"<<endl;  
  39.         cin>>a;  
  40.         cout<<"请输入运算符(+,-,*,/)"<<endl;  
  41.         cin>>op;  
  42.         cout<<"请输入数字B"<<endl;  
  43.         cin>>b;  
  44.         int A=atoi(a.c_str());  
  45.         int B=atoi(b.c_str());  
  46.           
  47.         result = operation.GetResult(A,B,op);  
  48.           
  49.         cout<<"result="<<result<<endl;  
  50.     }  
  51.     catch(exception &e)  
  52.     {  
  53.         cout<<"Exception:"<<e.what()<<endl;     
  54.     }  
  55.       
  56.     return 0;  
  57. }  

试想,如果想增加一个sqrt()。是不是还是要阅读源代码,然后在相应位置添加实现sqrt()的源代码,才可以实现。

如何才能实现松耦合呢?

采用面向对象技术的继承就可以。

菜鸟进阶二


[html]  view plain copy
  1. #include <iostream>  
  2. #include <exception>  
  3.   
  4. using namespace std;  
  5.   
  6. class Operation //操作运算基类   
  7. {  
  8. public:  
  9.     Operation(){}  
  10.     ~Operation(){}  
  11. public:  
  12.     double numberA;  
  13.     double numberB;  
  14.     char operate ;  
  15. public:  
  16.     void setNumberA(double number)//设置第一个操作数   
  17.     {  
  18.         numberA = number;  
  19.     }  
  20.     double getNumberA() //获取第一个操作数   
  21.     {  
  22.         return numberA;  
  23.     }  
  24.   
  25.     void setNumberB(double number)  
  26.     {  
  27.         numberB = number;  
  28.     }  
  29.     double getNumberB()  
  30.     {  
  31.         return numberB;  
  32.     }  
  33.   
  34. public:  
  35.     virtual double GetResult() //虚拟类   
  36.     {  
  37.         double result = 0;  
  38.         return result;  
  39.     }  
  40. };  
  41.   
  42.   
  43. class OperationAdd :public Operation  
  44. {  
  45. public:  
  46.     OperationAdd(void){}  
  47.     ~OperationAdd(void){}  
  48. public:  
  49.     double GetResult()  //重载基类中方法,实现加法   
  50.     {  
  51.         double result = 0;  
  52.         result = numberA + numberB;  
  53.         return result;  
  54.     }  
  55. };  
  56.   
  57. class OperationSub :public Operation  
  58. {  
  59. public:  
  60.     OperationSub(void){}  
  61.   
  62.     ~OperationSub(void){}  
  63. public:  
  64.     double GetResult()//重载基类中方法,实现减法   
  65.     {  
  66.         double result = 0;  
  67.         result =numberA - numberB;  
  68.         return result;  
  69.     }  
  70.   
  71. };  
  72.   
  73. class OperationMul :public Operation  
  74. {  
  75. public:  
  76.     OperationMul(void){}  
  77.     ~OperationMul(void){}  
  78. public:  
  79.     double GetResult()//重载基类中方法,实现乘法   
  80.     {  
  81.         double result = 0;  
  82.         result =numberA * numberB;  
  83.         return result;  
  84.     }  
  85. };  
  86.   
  87.   
  88. class OperationDiv :public Operation  
  89. {  
  90. public:  
  91.     OperationDiv(void){}  
  92.   
  93.     ~OperationDiv(void){}  
  94. public:  
  95.     double GetResult()//重载基类中方法,实现除法   
  96.     {  
  97.         double result = 0;  
  98.         result =numberA / numberB;  
  99.         return result;  
  100.     }  
  101. };  
  102.   
  103. class OperationFactory//运算工厂类   
  104. {  
  105. public:  
  106.     OperationFactory(){}  
  107.     ~OperationFactory(){}  
  108. public:  
  109.     Operation *oper; //运算基类 可以生成不同运算的子类(+,-,*,/)   
  110. public :  
  111.     Operation *createOperate(char operate) //返回类型是指针   
  112.     {  
  113.         switch (operate)  
  114.         {  
  115.         case '+':  
  116.             {  
  117.                 oper = new OperationAdd();  
  118.                 break;  
  119.             }  
  120.         case '-':  
  121.             {  
  122.                 oper = new OperationSub();  
  123.                 break;  
  124.             }  
  125.         case '*':  
  126.             {  
  127.                 oper = new OperationMul();  
  128.                 break;  
  129.             }  
  130.         case '/':  
  131.             {  
  132.                 oper = new OperationDiv();  
  133.                 break;  
  134.             }  
  135.         }  
  136.   
  137.         return oper;  
  138.     }  
  139. };  
  140.   
  141. int main()  
  142. {  
  143.     double strNumberA,strNumberB, result;  
  144.     char  strOperation;  
  145.     Operation *oper;  
  146.     OperationFactory factory;  
  147.     oper = factory.createOperate('*');  
  148.     oper->setNumberA(2);  
  149.     oper->setNumberB(4);  
  150.     result = oper->GetResult(); //调用的运算工厂返回的,各个操作运算符生成的对象  
  151.       
  152.     cout<<"result="<<result<<endl;   
  153.     return 0;  
  154. }  

整个程序结构说明:

class Operation                                       //操作运算基类 ,包含运算所必须的操作运算符和操作数,提供设定操作数和返回操作数方法

class OperationAdd :public Operation  //加法运算子类,设定运算结果

class OperationSub :public Operation  //减法运算子类

class OperationMul :public Operation  //乘法运算子类

class OperationDiv :public Operation  //除法运算子类

class OperationFactory                         //运算工厂类 ,负责生成各个操作运算符的类。


【注意】Operation *createOperate(char operate) //返回类型是指针



主要构成结构为: 操作运算符基类:定义操作必须的运算符和操作数,提供设定操作数和返回操作数方法

                                 四种运算子类:继承操作运算符基类,并实现每种运算符下的结果

                                 运算工厂:根据传递参数,生成不同运算符子类返回相应结果

                                 客户端:建立操作符基类,根据工厂生成子类,然后返回结果。

参考来源:http://blog.csdn.net/tianshuai11/article/details/7671097

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单工厂模式 的相关文章

  • 将类转换为 JSONObject

    我有好几堂这样的课 我想将类转换为 JSONObject 格式 import java io Serializable import com google gson annotations SerializedName public cla
  • 所有事件的 HTML5 EventSource 监听器?

    我使用 EventSource 在 JavaScript 客户端应用程序中推送通知 我可以像这样附加事件监听器 source addEventListener my custom event type function e console
  • 为什么 jar 执行的通配符在 docker CMD 中不起作用?

    我有一个Dockerfile与以下CMD启动我的 Spring Boot 应用程序 FROM java 8 jre CMD java jar app file jar 当我尝试从创建的图像启动容器时 我得到 Error Unable to
  • Java AES 256 加密

    我有下面的 java 代码来加密使用 64 个字符密钥的字符串 我的问题是这会是 AES 256 加密吗 String keyString C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE
  • ThreeTen 向后移植与 JSR-310 的比较

    由于某些原因 我们现在无法使用 java 8 我们仍然停留在 java 7 上 不过 我想使用新的JSR 310 date time APIs现在 使用官方向后移植 ThreeTen http www threeten org threet
  • 在光标所在行强制关闭!

    嘿 我正在尝试创建一个应用程序来查找存储在 SQlite 数据库中的 GPS 数据 但我面临一个问题 我构建了一个 DbAdapter 类来创建数据库 现在我尝试使用以下函数从另一个类获取所有数据上的光标 public Cursor fet
  • 使用 JDBC 连接到 PostgreSql 的本地实例

    我在 Linux 机器上有一个正在运行的 PostgreSql 本地实例 当我使用psql来自 shell 的命令我成功登录 没有任何问题 我需要通过 JDBC 连接到 PostgreSql 但我不知道我到底应该传递什么url参数为Driv
  • 为什么解析这个 JSON 会抛出错误?

    我正在尝试解析这个 JSONObject query yahoo count 1 results rate Name USD INR id USDINR Time 12 19pm Date 10 31 2015 Bid 65 405 Ask
  • 如何使用双重调度来分析图形基元的交集?

    我正在分析图形基元 矩形 直线 圆形等 的交互并计算重叠 相对方向 合并等 这被引用为双重调度的一个主要示例 例如维基百科 http en wikipedia org wiki Double dispatch 自适应碰撞算法通常要求 不同的
  • 如何在 IntelliJ IDEA 中运行 akka actor

    来自 Akka 网站文档 然后 这个主要方法将创建所需的基础设施 运行演员 启动给定的主要演员并安排 一旦主要参与者终止 整个应用程序就会关闭 因此 您将能够使用类似于以下的命令运行上面的代码 下列的 java classpath akka
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • 如何使用 poedit 解析 Timber(树枝)模板并检测要翻译的引用字符串

    我想用 poedit 解析 Timber 的树枝模板 并且需要翻译引用的内容 问题是我找不到不跳过引用内容的解析器 Example
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • 以 HTML 格式发送电子邮件

    我想发送 HTML 格式的电子邮件 如下图所示 我怎样才能做到这一点 请帮我 提前致谢 String body new String table tr td br header td tr br br Get b Best Score b
  • Azure Java SDK:ServiceException:ForbiddenError:

    尝试了基本位置检索器代码 如下所示 String uri https management core windows net String subscriptionId XXXXXXXX 5fad XXXXXX 9dfa XXXXXX St
  • 我所有的 java 应用程序现在都会抛出 java.awt.headlessException

    所以几天前我有几个工作Java应用程序使用Swing图书馆 JFrame尤其 他们都工作得很好 现在他们都抛出了这个异常 java awt headlessexception 我不知道是什么改变了也许我的Java版本不小心更新了 谢谢你尽你
  • Spring Data Rest 多对多 POST

    首先 让我解释一下我的用例 这非常简单 有一个用户实体和一个服务实体 我使用 UserService 作为连接实体 连接表 在用户和服务之间建立多对多关联最初 会有一些用户集和一些服务集 用户可以在任何时间点订阅任何服务 在这种情况下 将向
  • 带 getClassLoader 和不带 getClassLoader 的 getResourceAsStream 有什么区别?

    我想知道以下两者之间的区别 MyClass class getClassLoader getResourceAsStream path to my properties and MyClass class getResourceAsStre
  • iframe 主体删除空间

    我的 iframe 风格为style width 100 几乎覆盖了页面宽度 但它在左侧和右侧留下了一个小边距 所以我添加了body margin 0px 删除空间 它有效 但问题是删除边距影响其他事物 例如段落 p inside 有没有办
  • 设置 TreeSet 的大小

    有没有办法像数组一样对 Java 集合中的 TreeSet 进行大小限制 例如我们在数组中 anArray new int 10 数组具有固定长度 在创建数组时必须指定该长度 A TreeSet当您向其中添加元素时会自动增长 您无法设置其大

随机推荐

  • Nginx 无法转发本地端口

    问题描述 本文主要分析解决 centos 下 nginx 配置端口转发后不生效 通过 nginx 配置 server 转发后 无法达到预期的转发目的 并出现502错误的问题 假设虚拟机 ip 为 192 168 0 8 并且在虚拟机内部署一
  • ISO七层模型

    物理层 O S I 模型的最低层或第一层 该层包括物理连网媒介 如电缆连线连接器 物理层的协议产生并检测电压以便发送和接收携带数据的信号 在你的桌面P C 上插入网络接口卡 你就建立了计算机连网的基础 换言之 你提供了一个物理层 尽管物理层
  • uni-app项目在微信开发者工具打开时报错[ app.json 文件内容错误] app.json: 在项目根目录未找到 app.json

    uni app项目在微信开发者工具打开时控制台报错 app json 文件内容错误 app json 在项目根目录未找到 app json env Windows mp 1 06 2303220 lib 2 32 0 解决方案 以下是一个u
  • 前端基础之ES6

    1 前后端对比 2 ES6 ECMAScript6 0 以下简称ES6 ECMAScript是一种由Ecma国际通过ECMA 262标准化的脚本 是JavaScript语言的下一代标准 2015年6月正式发布 从ES6开始的版本号采用年号
  • S-DES加密

    S DES加密 Simplified Data Encryption Standard S DES 是一个供教学的非安全的加密算法 它与DES的特性和结构类似 但参数小 明文分组为8位 主密钥分组为10位 采用两轮迭代 S DES加密过程包
  • 第十一讲、FPGA开发中xilinx vivado 平台时序分析系列课程-边沿对齐input delay ddr双沿采样时序约束与收敛

    我们在使用一些以太网PHY和FPGA接口是RGMII接口是DDR双沿结构 还有ADC芯片也也是DDR双沿采样接口 以及CMOS视频传感器也有很多DDR双沿源同步接口 我们这里以IMX222视频传感器的的DDR为例约束input ddr 接口
  • FPGA提示产生latch的报错

    在fpga的设计中有时会遇到 latch 的报错 1 latch是什么 Latch 就是锁存器 是一种在异步电路系统中 对输入信号电平敏感的单元 用来存储信息 锁存器在数据锁存使能时 数据被锁存 输入信号不起作用 这违背了组合逻辑中输出随输
  • selenium元素定位方法 id,name,class

    1 导入selenium from selenium import webdriver from time import sleep 2 打开浏览器 最大化 driver webdriver Chrome driver maximize w
  • Java 学习路线大全,再也不用迷路啦(持续更新)

    路线特点 最新 完整一条龙 从入门到入土 表示推荐学习 给出目标 学习建议 关键知识点 最优资源以及各类资源推荐 视频 书籍 文档 项目 工具等 划分阶段 更有计划 且在最后给出持续学习的方向 探索 Java 程序员发展的无限可能 前言 首
  • SQLSERVER排查CPU占用高的情况

    一般排查都是用下面的脚本 一般会用到三个视图 sys sysprocesses dm exec sessions dm exec requests sys sysprocesses 系统表是一个很重要的系统视图 主要用来定位与解决Sql S
  • 存储类型auto,static,extern,register的区别 <转>

    变量和函数的属性包括数据类型和数据的存储类别 存储类别指数据在内存中存储方式 静态和动态 包含auto static register extern四种 内存中 具体点来说内存分为三块 静态区 堆区 栈区 外部变量和全局变量存放在静态区 局
  • 半监督学习——数据精馏(论文阅读)

    论文地址 https arxiv org pdf 1712 04440 pdf 1 论文与摘要 Data Distillation Towards Omni Supervised Learning 摘要 作者提出一种特殊的半监督学习方法 取
  • android 最新动态,浅谈Android动态页面(一)

    这是一个很微妙的东西 可能平时经常用到 但是没注意 我想对这个内容进行一个总结并提出一些看法 谈的是动态页面 不是动态布局 一 什么是动态页面 什么是动态页面 我认为是一种在开发时的设计思想 最终展示的页面会随着数据的改变而改变 或者说会根
  • OpenCV中如何读取URL图像文件

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 由来 最近知识星球收到的提问 觉得是一个很有趣的问题 就通过搜集整理归纳了一番 主要思想是通过URL解析来生成数据 转为图像 Mat对象 但是在Python语言与C 语言
  • Java基础学习总结(1)——equals方法

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 一 equals方法介绍 1 1 通过下面的例子掌握equals的用法 1 package cn galc test 2 3 public class TestEquals
  • 简单spring cloud服务升级实现

    1 升级原则 隔离性 v1升级到v2时 相互独立 互不不干扰 稳定性 服务不停止 完成升级 接口保持畅通 2 具体实现 2 1 eureka项目 搭建eureka 网上很多 就省略了 2 2 feign接口项目 2 2 1 依赖
  • React Hooks

    React Hooks 为什么使用 React Hook useState hook useReducer hook useEffect hook useRef hook useLayoutEffect hook useImperative
  • GPIO口的八种工作状态

    一直对GPIO的工作状态不是很熟悉 导致在设置IO状态时 经常会设置成推挽上拉 或者推挽下拉 开漏上拉等问题 虽然看起来没有影响MCU工作 但感觉这是一种无知的表现 现在总结下GPIO口的八种工作状态 其中四种输入状态 四种输出状态 一 输
  • (STM32笔记2)基于hc05的蓝牙实验

    实验任务 开机检测 HC05 蓝牙模块是否存在 如果检测不成功 则报错 检测成功之后 显示模块的主从状态 并显示模块是否处于连接状态 DS0 闪烁 提示程序运行正常 按 KEY0 按键 可以开启 关闭自动发送数据 通过蓝牙模块发送 按 KE
  • 简单工厂模式

    简单工厂模式 一 概念 从设计模式的类型上来说 简单工厂模式是属于创建型模式 又叫做静态工厂方法 StaticFactory Method 模式 但不属于23种GOF设计模式之一 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例 简