简单工厂模式

简介: 简单工厂模式

前言

假如目前有一个需求,需要你利用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.客户端不用关心服务端对象的创建过程

原理

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

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

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

优缺点

优点

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

缺点

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

目录
相关文章
|
10月前
|
人工智能 运维 JavaScript
通义灵码 SWE-GPT:从 静态代码建模 迈向 软件开发过程长链推理
在本文中,作者介绍了 Lingma SWE-GPT,一款专为解决复杂软件改进任务设计的开源大型语言模型系列。
475 30
|
10月前
|
人工智能 Kubernetes 云计算
第五届CID大会成功举办,阿里云基础设施加速AI智能产业发展!
2024年10月19日,第五届中国云计算基础架构开发者大会(CID)在北京朗丽兹西山花园酒店成功举办。本次大会汇聚了来自云计算领域的众多精英,不同背景的与会者齐聚一堂,共同探讨云计算技术的最新发展与未来趋势。
|
Dart 前端开发 UED
【Flutter前端技术开发专栏】深入理解Flutter中的流(Streams)和异步编程
【4月更文挑战第30天】探索Flutter的异步编程与流:了解异步编程在提升响应性和避免阻塞中的作用,掌握Stream、StreamController和StreamSubscription核心概念。通过实践案例学习如何使用流处理网络请求,提升应用性能。参考Dart和Flutter官方文档,深入理解并运用异步模式,如回调、async/await和Futures,构建更佳用户体验的Flutter应用。
212 0
【Flutter前端技术开发专栏】深入理解Flutter中的流(Streams)和异步编程
|
机器学习/深度学习 自然语言处理
代码识别模型有哪些
代码识别模型有哪些
304 1
|
NoSQL Java 关系型数据库
阿里P7Java最全面试296题:阿里天猫、蚂蚁金服含答案文档解析
阿里天猫、蚂蚁、钉钉面试专题题目加答案】 不会做别着急:文末有答案以及视频讲解,架构师资料 1. junit用法,before,beforeClass,after, afterClass的执行顺序 2. 分布式锁
|
弹性计算 运维 监控
【送书】实现可观测性平台的技术要点是什么?
【送书】实现可观测性平台的技术要点是什么?
【送书】实现可观测性平台的技术要点是什么?
|
缓存 Ubuntu Shell
Anaconda安装及入门教程(Windows、Ubuntu)
Anaconda安装及入门教程(Windows、Ubuntu)
831 1
Anaconda安装及入门教程(Windows、Ubuntu)
|
前端开发 安全 架构师
Spring认证证书有用吗?
Spring认证(全称:Spring Professional认证)是Spring官方推出的认证体系
Spring认证证书有用吗?
|
机器学习/深度学习 算法 数据可视化
【机器学习常见算法】决策树算法(含示例代码)
【机器学习常见算法】决策树算法(含示例代码)
470 0
【机器学习常见算法】决策树算法(含示例代码)
|
Java 数据库连接 Spring
Java基础内容之JVM钩子hooks函数
请问在Spring中,如果JVM异常终止,Spring是如何保证会释放掉占用的资源,比如说数据库连接等资源呢? 钩子函数非常简单,简单到小编只用摘抄一段Spring代码即可。走你,现在开始。
476 0