设计模式之简单工厂

article/2024/6/13 22:39:29
  • 现在有一个这样的需求:控制台输入俩个数,并输入运算符,计算并输出结果。上述需求乍一看,特别像一个小型的计算器,记得初学Java时,实现过。

实现一:

  • 创建计算器类,控制台输入俩个数以及运算符,通过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类并编译,不安全而且会影响到正常运行的代码。我突然想到了Java是面向对象的,面向对象的三大特性:多态、继承、封装。封装我们用到了,但是多态和继承没有用到,怎么样通过这俩个解决我刚才想到的那个问题呢?我查阅并思考了一下,于是就有了实现三。

实现三:

  • 增加类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分支即可。
  • 上述就是简单工厂模式的一些内容,大家如果有什么想法可以在评论区交流或者私信我。

​​计算器相关类结构图
计算器相关类结构图


http://www.ngui.cc/article/show-845536.html

相关文章

2、SPSS的基本知识

目录 一、SPSS软件的安装和启动 二、SPSS的基本操作环境 (1)数据编辑窗口(主程序窗口) (2)SPSS结果输出窗口 三、SPSS软件的退出 四、SPSS软件的三种基本使用方式 五、SPSS数据的结构和定义方法 1.…

人事管理系统

人才是单位的宝贵财富,而人事管理是人才资源的核心,因此快捷、高效的人事档案理系统成为单位的基本需求。 系统的主要目的是实现企业人事的信息化管理,主要业务是实现对员工信息的管理。 一、功能需求分析 人事管理系统主要是对人事档案管理…

(Java高级教程)第四章必备前端基础知识-第三节2:JavaScript数组、函数和对象

文章目录一:数组二:函数三:对象一:数组 数组:JavaScript中的数组和Java中的ArrayList有点相似,可以动态扩容,并且由于它是动态类型的语言,所以数组内的元素类型不要求一定是相同的 …

八字-十天干、十二地支、六十甲子

六十甲子是十天干与十二地支的组合,60为一周期,用年、月、日、时四个柱子撑起时间的大厦,所以年月日时也称四柱:甲子,乙丑,……,葵亥(一共60)。 十天干:甲乙丙丁卯己庚辛…

Shiro学习文档

Shiro Java安全框架 1.什么是权限管理 ​ 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。 权限管理…

实时即未来,大数据项目车联网之驾驶行程主任务定义【十六】

文章目录 1. 驾驶行程入库1.1 驾驶行程主任务定义1.2 自定义驾驶行程window function1.3 驾驶行程分析结果数据写入hbase1. 驾驶行程入库 驾驶行程数据筛选入库,为第六节的行程指标的分析数据 驾驶行程入库结果字段: vin :车架号 lastSoc:上次报文soc lastMileage:上次报文…

力扣1073. 负二进制数相加 C++

思路 正常如果看二进制不太好看出来规律,得拆开看 如 [1,1,1,1,1][1,0,1]列竖式也看不出来啥 列成这样 (-2)^4(-2)^3(-2)^2(-2)^1(-2)^0(-2)^2 (-2)^0可以看出来两个(-2)2和(-2)0 两个可以变成2^3和2,就可以和前面一位的1抵消,同时这…

记一次nginx崩溃事件

一、事件描述 2023年春节复工第一天,项目组同事反馈说业务系统中图像处理代理Nginx服务于1月23日发生崩溃,完成了重启操作,检查nginx的日志有如下报错: 2023/01/23 11:07:07 [crit] 3237#3237: *2253009 pwritev() "/var/c…

mysql:如何在windows环境下配置并随意切换两种mysql版本

系列文章目录 文章目录系列文章目录前言一、去官网下载zip安装包二、配置创建my.ini文件2.环境变量3、使用管理员身份打开dos命令窗口4、安装mysql8的服务和初始化data5、启动6 错误解决:修改mysql8服务的注册表最后前言 之前安装过5.7的版本 后来由于需要 就安装了…

【Ambari】ambari中添加新服务

背景 栈的定义可以在源代码树中找到/ambari-server/src/main/resources/stacks。当你安装Ambari Server服务之后&#xff0c;栈的定义可以被发现/var/lib/ambari-server/resources/stacks。 结构 一个栈的结构定义如下 |_ stacks|_ <stack_name>|_ <stack_version…