当前位置: 首页 > news >正文

设计模式——工厂三兄弟之简单工厂

1.业务需求

​ 大家好,我是菠菜。在介绍这期简单工厂设计模式前,我们先来看看这样的需求:制作一个简单的计算器,能够实现控制台输入俩个数以及运算符完成运算
计算器

2.初步实现

实现第一版思路:

​ 创建计算器类,控制台输入俩个数以及运算符,通过if条件输出运算结果。

CalClient 类:

public class CalClient {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入第一个数:");double numbera=sc.nextDouble();System.out.println("请输入运算符:");String operator=sc.next();System.out.println("请输入第二个数:");double numberb=sc.nextDouble();if("+".equals(operator)){System.out.println("运算结果为:"+(numbera+numberb));}else  if("-".equals(operator)){System.out.println("运算结果为:"+(numbera-numberb));}else  if("*".equals(operator)){System.out.println("运算结果为:"+(numbera*numberb));}else  if("/".equals(operator)){if(numberb==0){System.out.println("除数不能为零");return;}System.out.println("运算结果为:"+(numbera/numberb));}}
}

思考:这段代码在当时初学编程来说,没有问题,而且结果都能执行成功并输出。但是现在我们再来看是不是有点不太满意的地方,比如:计算控制台逻辑和计算方法逻辑耦合在一起,不满足上一期我们所学的单一职责原则,于是我又优化了一版。

实现第二版思路:

​ 增加Operation运算类,将计算方法封装到里面,把计算控制台逻辑和计算方法拆开,降低耦合。

Operation类:

public class Operation {public static Double getOperationResult(double numbera,double numberb,String operator){Double result=null;switch (operator){case "+":result=numbera+numberb;break;case "-":result=numbera-numberb;break;case "*":result=numbera*numberb;break;case "/":if(numberb==0){System.out.println("除数不能为零");return result;}result=numbera/numberb;break;}return result;}
}

CalClient类:

public class CalClient {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入第一个数:");double numbera=sc.nextDouble();System.out.println("请输入运算符:");String operator=sc.next();System.out.println("请输入第二个数:");double numberb=sc.nextDouble();//2.将业务逻辑和界面逻辑分开 解耦System.out.println("运算结果为:"+(Operation.getOperationResult(numbera,numberb,operator)));}
}

​ **思考:**上述代码,虽然将控制台和计算方法解耦,而且这个计算方法类可以做到一定程度上的复用,但是又有了一些新的问题:后续添加或修改计算方法要修改整个Operation类并编译,不安全而且会影响到正常运行的代码,而且该设计没有面向对象编程。我思考了一下,于是就有了下一个升级版本。

3.方案改进

实现第三版本思路:

​ 增加类OperationFactory,用于实例化具体的计算实例。增加抽象类AOpeartion,提取统一计算方法。增加计算实现类OperationAdd、OperationSub、OperationMul、OperationDiv。

计算器简单工厂模式

OperationFactory类:

public class OperationFactory {public static AOpeartion createOperation(String operator){AOpeartion opeartion=null;switch (operator){case "+":opeartion=new OperationAdd();break;case "-":opeartion=new OperationSub();break;case "*":opeartion=new OperationMul();break;case "/":opeartion=new OperationDiv();break;}return opeartion;}
}

AOpeartion类:

public abstract class AOpeartion {public abstract Double getOperationResult(double numbera, double numberb);
}

OperationAdd类:

public class OperationAdd extends AOpeartion {@Overridepublic Double getOperationResult(double numbera, double numberb) {return numbera+numberb;}
}

OperationSub类:

public class OperationSub extends AOpeartion {@Overridepublic Double getOperationResult(double numbera, double numberb) {return numbera-numberb;}
}

OperationMul类:

public class OperationMul extends AOpeartion {@Overridepublic Double getOperationResult(double numbera, double numberb) {return numbera*numberb;}
}

OperationDiv类:

public class OperationDiv extends AOpeartion {@Overridepublic Double getOperationResult(double numbera, double numberb) {if(numberb==0){System.out.println("除数不能为零");return null;}return numbera/numberb;}
}

CalClient类:

public class CalClient {public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("请输入第一个数:");double numbera=sc.nextDouble();System.out.println("请输入运算符:");String operator=sc.next();System.out.println("请输入第二个数:");double numberb=sc.nextDouble();//3.利用简单工厂实现 易维护 易复用 易拓展AOpeartion opeartion=OperationFactory.createOperation(operator);if(null!=opeartion){System.out.println("运算结果为:"+(opeartion.getOperationResult(numbera,numberb)));}else{System.out.println("运算工厂获取运算类失败");}}
}

​ 思考:OperationFactory工厂类通过输入的运算符去实例化相应合适的对象,通过多态返回父类的方式实现了计算器的结果。后续如果修改具体的计算方法只要修改具体的计算类即可,不会影响其它计算类。如果增加计算方法,增加实现相应的计算类的具体子类以及增加计算工厂类的switch分支即可。

4.定义和组成结构

​ 工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。按实际业务场景划分,工厂模式有 3 种不同的实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。

简单工厂模式的主要角色如下:

​ 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
​ 抽象产品(AbstractProduct):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
​ 具体产品(ConcreteProduct):是简单工厂模式的具体创建目标。

简单工厂模式

5.优缺点以及应用场景

优点:

  • 简单工厂模式实现了对象创建和使用的分离,职责分明
  • 客户端无需知道所创建具体对象的类名,只需知道参数即可

缺点:

  • 工厂类集中了所有产品的创建逻辑,职责过重
  • 系统扩展困难,添加新产品要修改原有逻辑,违反了开闭原则,产品种类一多,工厂类逻辑过于复杂,不利有扩展和维护

应用场景: 对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

友情提示:请尊重作者劳动成果,如需转载本博客文章请注明出处!谢谢合作!
【作者:我爱吃菠菜 个人博客地址

相关文章:

设计模式——工厂三兄弟之简单工厂

1.业务需求 ​ 大家好,我是菠菜。在介绍这期简单工厂设计模式前,我们先来看看这样的需求:制作一个简单的计算器,能够实现控制台输入俩个数以及运算符完成运算。 2.初步实现 实现第一版思路: ​ 创建计算器类&…...

如何使用ChatGPT撰写短视频爆款文案

在这个快速发展的数字时代,短视频已经成为最受欢迎的娱乐和信息获取方式之一。对于内容创作者来说,如何制作出爆款短视频,吸引更多观众的注意力,是他们面临的一大挑战。文案,作为视频内容的灵魂,起着至关重…...

申办风景园林设计乙级资质如何整理技术人员的专业培训证明

整理技术人员的专业培训证明是申办风景园林设计乙级资质的重要环节,它直接关系到证明技术人员持续学习和专业能力提升的情况。以下是整理专业培训证明的一些建议步骤: 收集培训记录:首先,向所有参与设计工作的技术人员收集他们参加…...

类别型特征

#机器学习 #深度学习 #基础知识 #特征工程 #数据编码 背景 在现实生活中,我们面对的数据类型有很多,其中有的数据天然为数值类型具备数值意义,那么可以很自然地和算法结合,但是大部分数据他没有天然的数值意义,那么将他们送入到算法前,就需要对数据进行编码处理,将其转换为数…...

java医院管理系统源码(springboot+vue+mysql)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的医院管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 医院管理系统的主要使用者分…...

vue2 面试题

一、.vue的性能优化怎么做? 1.编码优化: 不要把所有的数据都放在data中;v-for时给每个元素绑定事件用事件代理;keep-alive缓存组件;尽可能拆分组件,提高复用性、维护性;key值要保证唯一&#…...

【JavaEE精炼宝库】多线程(3)线程安全 | synchronized

目录 一、线程安全 1.1 经典线程不安全案例: 1.2 线程安全的概念: 1.3 线程不安全的原因: 1.3.1 案例刨析: 1.3.2 线程不安全的名词解释: 1.3.3 Java 内存模型 (JMM): 1.3.4 解决线程不安全问题: 二…...

el-table-column两种方法处理特殊字段,插槽和函数

问题:后端返回的字段为数字 解决办法: {{ row[item.prop] 1 ? "启用" : "禁用" }} {{ row[item.prop] }} 最终果: 另外:如果多种状态时可用函数 {{ getStatus(row[item.prop]) }} {{ row[item.prop…...

huggingface笔记: accelerate estimate-memory 命令

探索可用于某一机器的潜在模型时,了解模型的大小以及它是否适合当前显卡的内存是一个非常复杂的问题。为了缓解这个问题,Accelerate 提供了一个 命令行命令 accelerate estimate-memory。 accelerate estimate-memory {MODEL_NAME} --library_name {LIBR…...

李飞飞亲自撰文:大模型不存在主观感觉能力,多少亿参数都不行

近日,李飞飞连同斯坦福大学以人为本人工智能研究所 HAI 联合主任 John Etchemendy 教授联合撰写了一篇文章,文章对 AI 到底有没有感觉能力(sentient)进行了深入探讨。 「空间智能是人工智能拼图中的关键一环。」知名「AI 教母」李…...

超级好用的C++实用库之套接字

💡 需要该C实用库源码的大佬们,可搜索微信公众号“希望睿智”。添加关注后,输入消息“超级好用的C实用库”,即可获得源码的下载链接。 概述 C中的Socket编程是实现网络通信的基础,允许程序通过网络与其他程序交换数据。…...

C++ | Leetcode C++题解之第108题将有序数组转换为二叉搜索树

题目&#xff1a; 题解&#xff1a; class Solution { public:TreeNode* sortedArrayToBST(vector<int>& nums) {return helper(nums, 0, nums.size() - 1);}TreeNode* helper(vector<int>& nums, int left, int right) {if (left > right) {return nu…...

5月27日,每日信息差

第一、韩国宇宙航空厅于 5 月 27 日正式成立&#xff0c;旨在推动以民间为主的太空产业生态圈发展&#xff0c;助力韩国成为航天强国。首任厅长尹宁彬表示&#xff0c;该机构将在庆尚南道泗川市的临时大楼开展相关工作。 第二、京东集团宣布&#xff0c;自2024年7月1日起&…...

echart扩展插件词云echarts-wordcloud

echart扩展插件词云echarts-wordcloud 一、效果图二、主要代码 一、效果图 二、主要代码 // 安装插件 npm i echarts-wordcloud -Simport * as echarts from echarts; import echarts-wordcloud; //下载插件echarts-wordcloud import wordcloudBg from /components/wordcloudB…...

解决无法直接抓取链接地址

当我们在爬取一些文章列表的时候&#xff0c;可能无法从接口或者html界面上获取到文章的详细列表 这个时候我们可以通过模拟点击且重写window.open方法&#xff0c;将跳转的地址捕获&#xff0c;并且放到html中去。 这样我们就可以获取到某个文章的详细地址了 // 保存原始的 …...

java面对对象编程-多态

介绍 方法的多态 多态是在继承&#xff0c;重载&#xff0c;重写的基础上实现的 我们可以看看这个代码 package b;public class main_ {public static void main(String[] args) { // graduate granew graduate(); // gra.cry();//这个时候&#xff0c;子类的cry方法就重写…...

【Sql Server】随机查询一条表记录,并重重温回顾下自定义函数的封装和使用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言随机查询语…...

基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善

前言 紧接上篇->基于C#开发web网页管理系统模板流程-登录界面和主界面_c#的网页编程-CSDN博客 已经完成了登录界面和主界面&#xff0c;本篇将完善主界面的管理员录入和编辑功能&#xff0c;事实上管理员录入和编辑的设计套路适用于所有静态表的录入和编辑 首先还是介绍一下…...

K8s证书过期处理

问题描述 本地有一个1master2worker的k8s集群&#xff0c;今天启动VMware虚拟机之后发现api-server没有起来&#xff0c;docker一直退出&#xff0c;这个集群是使用kubeadm安装的。 于是kubectl logs查看了日志&#xff0c;发现证书过期了 解决方案&#xff1a; 查看证书 #…...

刷题之路径总和Ⅲ(leetcode)

路径总和Ⅲ 这题和和《为K的数组》思路一致&#xff0c;也是用前缀表。 代码调试过&#xff0c;所以还加一部分用前序遍历数组和中序遍历数组构造二叉树的代码。 #include<vector> #include<unordered_map> #include<iostream> using namespace std; //Def…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...