设计模式之简单工厂

news2024/11/15 2:04:04
  • 现在有一个这样的需求:控制台输入俩个数,并输入运算符,计算并输出结果。上述需求乍一看,特别像一个小型的计算器,记得初学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 {
    @Override
    public Double getOperationResult(double numbera, double numberb) {
        return numbera+numberb;
    }
}

OperationSub类:

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

OperationMul类:

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

OperationDiv类:

public class OperationDiv extends AOpeartion {
    @Override
    public 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.coloradmin.cn/o/182344.html

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

相关文章

windows 10 本地配置Oracle19+用navicat连接

文章目录0.背景环境0.背景知识1.卸载旧版本、安装 oracle 192.配置3.用 Navicat 连接3.1 下载instantclient193.2 配置dll使能连接高版本oracle3.3 配置连接4. 相关操作命令5.本地命令行登录orclpdb下的用户0.背景环境 本机已安装oracle12和Navicat15,需要先彻底卸载…

【docker】基础知识梳理与使用

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker基础知识的梳理与使用 1. docker的理解 Registry(仓库):是一个集中存储与分发镜像的服务。最常用的Registry是…

油井远程监控解决方案

1.项目背景 油田生产过程中,由于井筒内存在着不同程度的缺陷,会产生各种问题。而油井开采设备的连续稳定运行是保证石油开采的首要条件,但是由于油田地域广阔,油井分布广泛,没有规则性的油井工作状况的监测和控制&…

Acwing4655. 重新排序(差分模板题)

给定一个数组 A 和一些查询 Li,Ri,求数组中第 Li 至第 Ri 个元素之和。 小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。 小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少? …

【树】二叉树的非递归遍历

非递归的遍历需要使用栈保存当前不输出的结点,并且三种遍历顺序步骤有所不同。中序遍历1.查看其当前结点是否为空:若非空则将当前结点入栈,指针指向其左孩子;若当前结点为空,说明上一个入栈的结点没有左孩子&#xff0…

vite+vue3+elementPlus搭建项目

创建基础框架 方式一: 创建命令 npm create vitelatest or yarn create vite 注意:这里可能会出现一个坑,注意你的node版本(node版本过低就会报错) 创建成功 创建成功后运行以下命令即可 yarn yarn dev 这种创建方…

C技能树-判断语句

三个数从小到大排序并输出 任意输入3个整数&#xff0c;使用if语句对这3个整数由小到大进行升序排序。请判断下面哪一项无法实现该功能。 #include <stdio.h>/* 交换x和y */ void swap(int* x, int* y) {int temp *x;*x *y;*y temp; }int main(int argc, char** arg…

[红明谷CTF 2021]write_shell

目录 信息收集 payload 补充知识 信息收集 代码审计 <?php error_reporting(0); highlight_file(__FILE__); function check($input){if(preg_match("/| |_|php|;|~|\\^|\\|eval|{|}/i",$input)){// if(preg_match("/| |_||php/",$input)){die(h…

(二十七)Map集合体系

目录 前言: 一、Map集合的遍历方式之一:键找值 二、Map集合的遍历方式之二:键值对 三、Map集合的遍历方式之三:Lambda表达式 四、Map集合的实现类HashMap 五、Map集合的实现类LinkedHashMap 六、Map集合的实现类TreeMap 七、不可变集合 前言: ①Map集合是一种双列集合&a…

机器学习中的聚类算法

1. 概述根据所拥有的数据&#xff0c;可以使用三种不同的机器学习方法&#xff0c;包括监督学习、半监督学习和无监督学习。在监督学习中&#xff0c;根据已标记数据&#xff0c;因此可以确定输出是关于输入的正确值。通过半监督学习&#xff0c;用户将拥有一个大型数据集&…

提高mysql性能:设计阶段

合适的表设计 基本原则 避免太多的列 太多的列会导致mysql从行缓存中将编码过的列转换为行数据时花费大量大代价。 减少太多的关联 为减少太多的关联造成解析和查询的性能影响&#xff0c;应该将单表的关联控制在12个之内。 合理使用枚举 枚举只适用于值相对固定&#x…

go入门——基础语法

go环境安装 1、安装 go官网&#xff1a;Downloads - The Go Programming Language (google.cn) go中文网&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 (studygolang.com) 这里我是amd64位win10系统&#xff0c;所以我下载这个 下载完成之后安装到自己喜欢的目录就好…

Java:基于XML的Spring使用【IOC容器】

基于XML的Spring使用一、Spring IOC 底层实现1.1 BeanFactory与ApplicationContexet1.2 图解IOC类的结构二、 Spring依赖注入数值问题【重点】2.1 字面量数值2.2 CDATA区2.3 外部已声明bean及级联属性赋值2.4 内部bean2.5 集合三、 Spring依赖注入方式【基于XML】3.1 set注入3.…

电子技术——MOS管的CV特性

电子技术——MOS管的CV特性 MOS管是一种压控晶体管&#xff0c;本节我们学习MOS管的CV特性&#xff0c;即电压-电流特性。MOS管的特性曲线有两种&#xff0c;分别是伏安特性和传导特性。 iD−vDSi_D-v_{DS}iD​−vDS​ 特性曲线 为了测量MOS管的 iD−vDSi_D-v_{DS}iD​−vDS​…

ctfshow黑盒测试篇

文章目录web380web381web382web383web384web385web386web387web388web389web390web391web392web393web394、395web380 目录扫出来了page.php $id应该是传的参数&#xff0c;是php的文件名 page.php?idflag 访问源码拿到flag web381 就是这个目录 /alsckdfy/ 访问就是flag …

力扣(LeetCode)1664. 生成平衡数组的方案数(C++/Python3)

题目描述 模拟 逆向思维&#xff08;删除元素的性质&#xff09;&#xff1a;删除数组的某个元素&#xff0c;左侧元素的下标不变&#xff0c;右侧元素的下标发生奇偶替换。 算法流程 ① 由于算法从右往左枚举&#xff0c;预处理左侧的奇数下标元素之和oddl&#xff0c;偶数下…

过万春节服务全是问题无语了-Harbor镜像仓库访问404

1、背景 春节后的周六补班&#xff0c;累啊&#xff0c;到公司发现docker和kubelet服务都被停止了&#xff0c;可能是春节期间担心发生安全隐患吧&#xff0c;服务启动后发现很多镜像无法拉取了 到相关的节点上去尝试拉取镜像发现报了404错误 docker pull xxx.xxx.xxx.xxx/d…

初学者如何学好Java数组,不妨点进来看看,赶在新年前肝完的万字博客

新年好~~~新年开篇万字博客 —Java数组的学习,有点干货,建议收藏观看!!! 本篇介绍了数组的概念,数组创建和初始化.数组的使用(元素访问,和数组遍历方法),初识引用数据类型,简单介绍JVM内存分布,认识null,堆区空间的释放 二维数组相关知识的介绍~ 学习Java中的数组一.数组的基本…

变增益PID(含5种变增益模式PLC源代码+Simulink仿真)

变增益PID的详细理论讲解和应用场景,请参看下面的文章链接: 增益自适应PI控制器+死区过滤器(Smart PLC向导PID编程应用)_RXXW_Dor的博客-CSDN博客增益自适应和死区过滤器如果不和S7-200 SMART PLC PID向导组合实现,大家可以自行编写优化的PID指令。算法起始非常简单,具体…

2 分钟就能抓取任何网站的数据是怎么做到的?? #Browse AI

尽管现在使用网络的方式或多或少与 20 年前相同&#xff0c;但网络在我们生活中占据的地位越来越重要&#xff0c;网站却变得越来越繁琐。最重要的是&#xff0c;即使网络上有大量有价值的实时数据&#xff0c;收集它们也是非常昂贵和耗时的。Browse AI 是一款可以从任何网站提…