简单工厂模式

简介: 简单工厂模式

前言

假如目前有一个需求,需要你利用Java编程语言实现一个计算器的功能。你会怎么实现呢?


一、最感性的代码直接输出

package com.shuyixiao.简单工厂模式;

import java.util.Scanner;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入第一个数字:");
        String one = sc.nextLine();

        System.out.println("请选择运算符号 (+ - * / ):");
        String two = sc.nextLine();

        System.out.println("请输入第二个数字:");
        String three = sc.nextLine();

        Double result = 0d;

        if (two.equals("+")){
            result = Double.parseDouble(one) + Double.parseDouble(three);
        } else if (two.equals("-")) {
            result = Double.parseDouble(one) - Double.parseDouble(three);
        } else if (two.equals("*")) {
            result = Double.parseDouble(one) * Double.parseDouble(three);
        } else if (two.equals("/")) {
            result = Double.parseDouble(one) / Double.parseDouble(three);
        }

        System.out.println("结果是" + result);
    }
}

上述代码当然可以实现计算器的功能,但是存在很多的问题,接下来我们一步步分析

1.上述代码首先临时变量名的命名不规范

2.没有对除法运算做容错判断,代码健壮性不好

3.存在大量重复的代码以及多处的if-else判断,存在无用功

二、感性代码的初步改进版本

package com.shuyixiao.简单工厂模式;

import java.util.Scanner;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Test2 {
    public static void main(String[] args) {
        try {
            Scanner sc = new Scanner(System.in);

            System.out.println("请输入第一个数字:");
            String one = sc.nextLine();

            System.out.println("请选择运算符号 (+ - * / ):");
            String two = sc.nextLine();

            System.out.println("请输入第二个数字:");
            String three = sc.nextLine();

            Double result = 0d;

            switch(two){
                case "+":
                result = Double.parseDouble(one) + Double.parseDouble(three);
                break;
                case "-":
                result = Double.parseDouble(one) - Double.parseDouble(three);
                break;
                case "*":
                result = Double.parseDouble(one) * Double.parseDouble(three);
                break;
                case "/":
                result = Double.parseDouble(one) / Double.parseDouble(three);
            }

            System.out.println("结果是" + result);
        } catch (NumberFormatException e) {
            System.out.println("你输入的参数有误");
        }
    }
}

通过使用switch case break判断的方式来替代if语句的判断提高性能

同时使用try catch捕捉的形式来增强代码的健壮性

但是还是存在面向过程编程的理念还是 没有转变

三、面向对象的编程方式实现

所谓的面向对象的编程方式就是将业务与逻辑分离,你干你的我写我的互不牵扯从而实现降低耦合度的效果

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Calculate {
    public static double Result(String one, String three,String two) {
        double result =0d;
        switch(two){
            case "+":
                result = Double.parseDouble(one) + Double.parseDouble(three);
                break;
            case "-":
                result = Double.parseDouble(one) - Double.parseDouble(three);
                break;
            case "*":
                result = Double.parseDouble(one) * Double.parseDouble(three);
                break;
            case "/":
                result = Double.parseDouble(one) / Double.parseDouble(three);
        }
        return result;
    }
}

客户端代码部分的展示

package com.shuyixiao.简单工厂模式;

import java.util.Scanner;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Customer {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入第一个数字:");
        String one = sc.nextLine();

        System.out.println("请选择运算符号 (+ - * / ):");
        String two = sc.nextLine();

        System.out.println("请输入第二个数字:");
        String three = sc.nextLine();

        double result = Calculate.Result(one, two, three);
        System.out.println("result = " + result);
    }
}

上述代码在使用面想对象编程思想之后虽然是解耦了一些但是还是存在问题,不满足对扩展开放对修改关闭的特点,假如我们需要使用计算机增加一项功能,例如此刻我想求某数的平方根那就有点困难需要去修改计算器中的类就有些许繁琐。

四、简单工厂模式的编程方式实现

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 * 定义这个抽象类 只在其中写共性的计算方法
 */
public abstract class CalculateFactory {
    public double result(String one,String two){
        return 0d;
    }
}

分别实现加减乘除的各自实现类

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Add extends CalculateFactory{
    @Override
    public double result(String one, String two) {
        return Double.parseDouble(one) + Double.parseDouble(two);
    }
}

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Mul extends CalculateFactory{
    @Override
    public double result(String one, String two) {
        return Double.parseDouble(one) - Double.parseDouble(two);
    }
}

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Sub extends CalculateFactory{
    @Override
    public double result(String one, String two) {
        return Double.parseDouble(one) * Double.parseDouble(two);
    }
}

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Sub extends CalculateFactory{
    @Override
    public double result(String one, String two) {
        return Double.parseDouble(one) * Double.parseDouble(two);
    }
}

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Div extends CalculateFactory{
    @Override
    public double result(String one, String two) {
        if(two.equals("0")){
            System.out.println("除数不能为0");
            throw new ArithmeticException();
        }
        return Double.parseDouble(one) / Double.parseDouble(two);
    }
}

在使用的使用我们需要使用工厂类进行实例对象来进行运算。

定义:个人感觉简单工厂不像是一种工厂,反而更加像是一种编程习惯。简单工厂又称为静态工厂方法模式。他是通过静态方法接收不同的参数来返回不同的实例对象。

实现方式:就是通过定义一个工厂类,根据传入的参数的不同来实例化出不同的对象。被创建的对象则具体共同的父类或者接口。

package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class SimpleFactory {
    public static CalculateFactory calculateFactory(String three){
        CalculateFactory calculateFactory = null;
        switch(three){ 
            case "+":
                calculateFactory = new Add();
            case "-":
                calculateFactory = new Mul();
            case "*":
                calculateFactory = new Sub();
            case "/":
                calculateFactory = new Div();
        }
        return calculateFactory;
    }
}


package com.shuyixiao.简单工厂模式;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class SimpleFactory {
    public static CalculateFactory calculateFactory(String three){
        CalculateFactory calculateFactory = null;
        switch(three){ 
            case "+":
                calculateFactory = new Add();
            case "-":
                calculateFactory = new Mul();
            case "*":
                calculateFactory = new Sub();
            case "/":
                calculateFactory = new Div();
        }
        return calculateFactory;
    }
}


package com.shuyixiao.简单工厂模式;

import java.util.Scanner;

/**
 * @author 舒一笑
 * @date 2023/4/28
 */
public class Customer {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入第一个数字:");
        String one = sc.nextLine();

        System.out.println("请选择运算符号 (+ - * / ):");
        String two = sc.nextLine();

        System.out.println("请输入第二个数字:");
        String three = sc.nextLine();
        

        CalculateFactory calculateFactory = SimpleFactory.calculateFactory(two);
        double result = calculateFactory.result(one, three);
        System.out.println("result = " + result);
    }
}

五、总结

适用场景

1.创建对象比较少

2.客户端不用关心服务端对象的创建过程

原理

抽象产品:通过抽象类或者接口定义产品的规范,就是在抽象类或者接口中写主要的特征或者功能点

具体产品:实现接口的实现类或者继承接口的子类

具体工厂:提供创建产品的静态方法。消费者调用该方法来获取产品

优缺点

优点

封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

缺点

增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。

相关文章
|
安全 网络安全 区块链
发现挖矿木马产生的网络安全,如何紧急应急响应
挖矿木马是利用各种方法入侵计算机,利用被入侵计算机的算力挖掘加密数字货币以牟取利益的木马。其既可以是一段自动化扫描、攻击的脚本,也可以集成在单个可执行文件中。挖矿木马为了能够长期在服务器中驻留,会采用多种安全对抗技术,如修改任务计划、修改防火墙配置、修改系统动态链接库等,使用这些技术手段严重时可能造成服务器业务中断。
|
6月前
|
Linux API 数据安全/隐私保护
无需技术储备!OpenClaw(阿里云/Win11/MacOS/Linux)部署步骤+千问/Coding Plan API配置+避坑指南
OpenClaw(前身为Clawdbot、Moltbot)作为2026年现象级开源AI助理项目,以“私有化运行+全权限实操”的核心定位,打破了传统聊天机器人“只说不做”的局限。它可部署在本地设备或云服务器上,通过自然语言指令完成文件管理、系统运维、邮件收发、网页抓取等实际操作,所有数据本地存储,隐私安全性拉满,成为个人与轻量团队提升效率的核心工具。
1034 2
|
存储 API 开发工具
DeepSeek 3FS解读与源码分析(5):客户端解读
本文深入解析了3FS的客户端模式,包括FUSE Client和Native Client(USRBIO)。
DeepSeek 3FS解读与源码分析(5):客户端解读
|
Java 分布式数据库 Docker
使用Docker配置并连接HBase的Java API
本流程概要的解释了如何在Docker上配置并启动HBase服务,并通过Java API进行连接和操作表,不涉及具体的业务逻辑处理和数据模型设计,这些因应用而异需由开发者根据实际需求进行实现。
587 13
|
存储 算法 安全
量子计算基础介绍
量子计算基础介绍
624 1
|
消息中间件 监控 Java
好文!12个策略解决 Kafka 数据丢失问题
以上这些策略对于解决 kafka 数据丢失问题很有帮助,如果你正在使用 kafka,或者正在学习 kafka,V 哥觉得你都应该把这12种策略收藏起来并消化掉,这对你在大型项目应用中非常有用。欢迎关注威哥爱编程,一起向技术大神进发。
1152 0
|
Android开发 开发者
Android经典面试题之SurfaceView和TextureView有什么区别?
分享了`SurfaceView`和`TextureView`在Android中的角色。`SurfaceView`适于视频/游戏,独立窗口低延迟,但变换受限;`TextureView`支持复杂变换,视图层级中渲染,适合动画/视频特效,但性能略低。两者在性能、变换、使用和层级上有差异,开发者需按需选择。
1182 1
|
算法 Java C++
《经典图论算法》迪杰斯特拉算法(Dijkstra)
这个是求最短路径的迪杰斯特拉算法,另外我还写了50多种《经典图论算法》,每种都使用C++和Java两种语言实现,熟练掌握之后无论是参加蓝桥杯,信奥赛,还是其他比赛,或者是面试,都能轻松应对。
echarts 提示框异步获取数据 —— formatter 异步回调函数的使用
echarts 提示框异步获取数据 —— formatter 异步回调函数的使用
912 0
|
XML 算法 C语言
干货 | 自适应大邻域搜索(ALNS)和禁忌搜索(TS)实验对比附代码
干货 | 自适应大邻域搜索(ALNS)和禁忌搜索(TS)实验对比附代码
2159 0
干货 | 自适应大邻域搜索(ALNS)和禁忌搜索(TS)实验对比附代码

热门文章

最新文章