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

聊聊设计模式--简单工厂模式

简单工厂模式

​ 前面也学了很多各种微服务架构的组件,包括后续的服务部署、代码管理、Docker等技术,那么作为后端人员,最重要的任务还是代码编写能力,如何让你的代码写的漂亮、易扩展,让别人一看赏心悦目,那么设计模式就是很重的了。那么本本篇文章就来聊聊一个简单的工厂模式。

缘起

​ 一个22岁刚毕业的大学生A,计算机专业学的Java语言,到B公司面试。而面试题非常简单,实现一个简易计算器的功能,A觉得面试题很简单,三下五除二直接10分钟完事儿了。然而交卷后,迟迟等不到B公司的通知,多半是凉了,那么他是怎么实现的呢?代码如下:

public class Test {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入数字A:");String A = sc.nextLine();System.out.println("请选择运算符(+、-、*、/):");String B = sc.nextLine();System.out.println("请输入数字B:");String C = sc.nextLine();double D = 0d;if (B.equals("+")) D = Double.parseDouble(A) + Double.parseDouble(C);if (B.equals("-")) D = Double.parseDouble(A) - Double.parseDouble(C);if (B.equals("*")) D = Double.parseDouble(A) * Double.parseDouble(C);if (B.equals("/")) D = Double.parseDouble(A) / Double.parseDouble(C);System.out.println("结果是:" + D);}}

那么就以上的代码,按功能来说,有问题吗?

没问题,功能确实实现了;但是细看就会发现代码规范及其他的问题:

  • 变量名命名问题:ABCD?
  • if判断问题,假如输入的是+号,那么其他的判断还有必要再去执行吗,没必要
  • 输入的不是数字时怎么处理

那么按照上面的问题,依次去改动代码

public class Test {public static void main(String[] args) {try {Scanner sc = new Scanner(System.in);System.out.println("请输入数字A:");double numberA = Double.parseDouble(sc.nextLine());System.out.println("请选择运算符(+、-、*、/):");String strOperate = sc.nextLine();System.out.println("请输入数字B:");double numberB = Double.parseDouble(sc.nextLine());double result = 0d;switch (strOperate) {case "+":result = numberA + numberB;break;case "-":result = numberA - numberB;break;case "*":result = numberA * numberB;break;case "/":result = numberA / numberB;break;}System.out.println("结果是:" + result);} catch (Exception e) {System.out.println("您的输入有误:" + e.getMessage());}}}

行了,代码规范的问题是都已经完善了。

那么如何提高代码的可维护、可扩展、可复用、灵活性更好呢?

答案就是面向对象。

业务的封装

准确的说,就是让业务逻辑和界面逻辑分开,让它们之间的耦合度下降,只有分离开,才可以达到容易维护和扩展。

增加一个运算类

public class Operation {public static double getResult(double numberA, double numberB, String operate) {double result = 0d;switch (operate) {case "+":result = numberA + numberB;break;case "-":result = numberA - numberB;break;case "*":result = numberA * numberB;break;case "/":result = numberA / numberB;break;}return result;}}

那么客户端Test的代码

public class Test {public static void main(String[] args) {try {Scanner sc = new Scanner(System.in);System.out.println("请输入数字A:");double numberA = Double.parseDouble(sc.nextLine());System.out.println("请选择运算符(+、-、*、/):");String strOperate = sc.nextLine();System.out.println("请输入数字B:");double numberB = Double.parseDouble(sc.nextLine());double result = Operation.getResult(numberA, numberB, strOperate);System.out.println("结果是:" + result);} catch (Exception e) {System.out.println("您的输入有误:" + e.getMessage());}}}

业务逻辑和界面逻辑都分离开了,那么这种方案就是面向对象的封装,三大特性之一。

增加功能

计算器的功能发生改变了,不仅要支持+-*/,我还想要加一个平方根运算,那我们就需要去修改Operation类中的代码

public class Operation {public static double getResult(double numberA, double numberB, String operate) {double result = 0d;switch (operate) {case "+":result = numberA + numberB;break;case "-":result = numberA - numberB;break;case "*":result = numberA * numberB;break;case "/":result = numberA / numberB;break;case "pow":result = Math.pow(numberA, numberB);break;}return result;}
}

那么问题来了,我这里是加了一个pow的case分支,加一个平方根运算的功能,但是却需要让加减乘除的运算全都得来参与编译,万一一个不小心,把加法运算改成减法了,又没有注意到,直接给上生产环境了,这之后造成的问题能承担的了吗?

那么我们为了增加功能,而不让其他已经存在的功能有代码误改的风险。继续对业务方法进行改进.

我们将Operation类置为抽象类,让其他的加减乘除继承它,并且每一个功能都是一个单独的类实现自己的业务逻辑

public abstract class Operation {public double getResult(double numberA, double numberB) {return 0d;}
}

加减乘除类

public class Add extends Operation { // 加@Overridepublic double getResult(double numberA, double numberB) {return numberA + numberB;}
}public class Sub extends Operation { // 减@Overridepublic double getResult(double numberA, double numberB) {return numberA - numberB;}
}public class Mul extends Operation { // 乘@Overridepublic double getResult(double numberA, double numberB) {return numberA * numberB;}
}public class Div extends Operation { // 除@Overridepublic double getResult(double numberA, double numberB) {if (numberB == 0) {System.out.println("除数不能为0");throw new RuntimeException();}return numberA / numberB;}
}

实现简单工厂

上面抽象出来一个操作类(Operation),并且有加减乘除的业务逻辑类,那么我如何得知,应该用哪个业务逻辑类呢?

这时候,我们就需要一个工厂类,工厂顾名思义就是用来加工的,我把原料放进去,工厂给我生产出来产品。

public class OperationFactory {  public static Operation createOperate(String operate) {Operation oper = null;switch (operate) {case "+":oper = new Add();break;case "-":oper = new Sub();break;case "*":oper = new Mul();break;case "/":oper = new Div();break;}return oper;}
}

客户端这里调用时

public class Test {public static void main(String[] args) {try {Scanner sc = new Scanner(System.in);System.out.println("请输入数字A:");double numberA = Double.parseDouble(sc.nextLine());System.out.println("请选择运算符(+、-、*、/):");String strOperate = sc.nextLine();System.out.println("请输入数字B:");double numberB = Double.parseDouble(sc.nextLine());Operation operate = OperationFactory.createOperate(strOperate);double result = operate.getResult(numberA, numberB);System.out.println("结果是:" + result);} catch (Exception e) {System.out.println("您的输入有误:" + e.getMessage());}}}

在这里插入图片描述

上面就是大致的结构图,当我们再次增加新的功能时,只需要去集成Operation运算类,然后实现自己的业务逻辑就可以了,看起来是不是比原先的一坨代码更加一目了然了,并且也提高了它的复用性、维护性、扩展性,也更加灵活了。

相关文章:

聊聊设计模式--简单工厂模式

简单工厂模式 ​ 前面也学了很多各种微服务架构的组件,包括后续的服务部署、代码管理、Docker等技术,那么作为后端人员,最重要的任务还是代码编写能力,如何让你的代码写的漂亮、易扩展,让别人一看赏心悦目&#xff0c…...

Python基础教程:内置函数之字典函数的使用方法

嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 len(字典名): 返回键的个数,即字典的长度 # len(字典名): # 返回键的个数,即字典的长度dic {a:123,b:456,c:789…...

Pytorch从零开始实战06

Pytorch从零开始实战——明星识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——明星识别环境准备数据集模型选择开始训练模型可视化模型预测总结 环境准备 本文基于Jupyter notebook,使用Python3.8,Pytorch2.0.1c…...

RT-Thread学习笔记(三):线程管理

线程管理 线程管理相关概念什么是时间片轮转调度器锁线程运行机制线程的五种状态 动态和静态创建线程区别动态和静态创建线程优缺点RT-Thread动态线程管理函数动态创建线程动态删除线程 RT-Thread静态线程管理函数静态创建线程 线程其他操作线程启动线程延时获得当前执行的线程…...

pymysql连接Mariadb/Mysql出现错误(配置正确情况下)解决办法

场景:在kali中使用python中pymysql对Mariadb进行连接,在整个过程中配置全部正确,但是就是无法进行连接,提示结果如下: Access denied for user rootlocalhost解决办法:进入数据库中,将默认密码…...

数据仓库扫盲系列(1):数据仓库诞生原因、基本特点、和数据库的区别

数据仓库的诞生原因 随着互联网的普及,信息技术已经深入到各行各业,并逐步融入到企业的日常运营中。然而,当前企业在信息化建设过程中遇到了一些困境与挑战。 1、历史数据积存。 过去企业的业务系统往往是在较长时间内建设的,很…...

DataX-web安装部署和使用

DataX-web的环境准备 MySQL (5.5) 必选,对应客户端可以选装, Linux服务上若安装mysql的客户端可以通过部署脚本快速初始化数据库 JDK (1.8.0_xxx) 必选 DataX 必选 Python (2.x) (支持Python3需要修改替换datax/bin下面的三个python文件,替换文件在do…...

sqlmap防御以及文件读写

一.防御 过滤 1.使用过滤函数 $email filter_var($_POST[email], FILTER_VALIDATE_EMAIL); if ($email) { // input is a valid email address } else { // input is not a valid email address 使用 filter_var() 函数和 FILTER_VALIDATE_EMAIL 过滤器来验证用户输…...

【源码】C/C++运动会计分系统 期末设计源码

文章目录 题目介绍功能源码效果展示带报告(内容) 题目介绍 使用语言: 两个版本都会发: 版本1:C语言 版本2: C 代码量: 500 题目介绍: 要求:初始化输入:N-参赛…...

Ubuntu安装Docker

卸载官方库中之前的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io更新安装包列表 sudo apt-get update安装以下包以使apt可以通过HTTPS使用存储库 sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common添…...

useReducer+createContext真的可以代替Redux吗?

概念 useReducer useReducer 是 React 提供的一个状态管理钩子,通常用于管理组件的复杂状态逻辑。它采用两个参数:reducer 函数和初始状态。Reducer 函数接受当前状态和一个操作(action),并返回一个新的状态。这有点…...

Mysql忘记登入密码找回 方法(超详细)

如果你找不到 MySQL 的安装路径,可以尝试以下几种方法: 检查环境变量:打开命令提示符,并运行以下命令: echo %PATH% 这会显示系统的环境变量。查找其中是否包含 MySQL 相关的路径,例如 C:\Program Files…...

NodeMCU ESP8266 读取按键外部输入信号详解(图文并茂)

NodeMCU ESP8266 读取按键外部输入信号教程(图文并茂) 文章目录 NodeMCU ESP8266 读取按键外部输入信号教程(图文并茂)前言按键输入常用接口pinModedigitalRead 示例代码结论 前言 ESP8266如何检测外部信号的输入,通常…...

Oracle如何插入图片数据?

1、创建表,注意:插入图片的列要定义成BLOB类型 create table image_lob(t_id varchar2(5) not null,t_image blob not null);2、创建图片目录,images为目录名 create or replace directory "images" as f:\pic\;3、创建存储过程&am…...

C++特性——inline内联函数

1. 内联函数 1.1 C语言的宏 在C语言中,我们学习了用#define定义的宏函数,例如: #define Add(x, y) ((x) (y)) //两数相加相较于函数,我们知道宏替换具有如下比较明显的优点: 性能优势: 宏在预处理阶段…...

pensieve运行的经验

1运行run_videopy时出现如下问题: cmd: Union[List[str], str], ^ SyntaxError: invalid syntax原因是EasyProcess版本与python版本不对应,解决办法可见之前这篇博客:SyntaxError: invalid syntax。 2解决完上述问题后,输…...

Qt实现一个电子相册

一、要实现的功能 在窗口中可以显示图片,并且能够通过两个按钮进行图片的前进和后退的顺序切换。有一个按钮,通过这个按钮可以从所存图片资源中随机选取一个图片进行展示通过按钮可以控制图片自动轮播顺序切换的开始与停止,显示当前系统的时…...

R语言:因子分析 factor analysis

文章目录 因子分析数据集处理步骤主成分法做因子分析最大似然法做因子分析因子分析 因子分析的用途与主成分分析类似,它也是一种降维方法。由于因子往往比主成分更易得到解释,故因子分析比主成分分析更容易成功,从而有更广泛的应用。 从方法上来说,因子分析比主成分分析更为…...

SOFAStack软件供应链安全产品解析——SCA软件成分分析

近年来,软件供应链安全相关攻击事件呈快速增长态势,造成的危害也越来越严重,为了保障软件供应链安全,各行业主管单位也出台了诸多政策及技术标准。基于内部多年的实践,蚂蚁数科金融级云原生PaaS平台SOFAStack发布完整的…...

vue中ElementUi的el-table表格绑定行点击事件

<el-table v-loading"loading" :data"messagesList" row-click"goToMassage">handleRowClick(row, event, column) {// 在这里处理行点击事件console.log(行点击事件&#xff1a;, row, event, column);}...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...