JAVA设计模式之-简单工厂模式

说到设计模式,可能大家觉得除了面试的八股文需要,只是简单的背了背,但并不知道为什么要使用。 本文将以一个简单的例子带大家了简单的工厂模式,以及为什么要使用。

假如现在有这么一道题目,让你用任意一种面向对象的语言实现一个计算器控制程序,要求输入两个数和运算符,得到结果

一、初学者的通病:

在这里插入图片描述
1、命名不规范

2、分支判断,这样的写法,意味着每个分支都要判断,等于做了三次无用功

3、除数可能为零,导致程序错误

4、大量重复的代码Double.parseDouble()

于是你做了如下修改,将if改成switch,并且引入try catch

public class TestTwo {
    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 sign = sc.nextLine();
            System.out.println("请输入数字B:");
            double numberB = Double.parseDouble(sc.nextLine());

            double result = 0d;

            switch (sign){
                case "+":
                    result = numberA + numberB;
                    break;
                case "-":
                    result = numberA - numberB;
                    break;
                case "*":
                    result = numberA * numberB;
                    break;
                case "/":
                    result = numberA / numberB;
                    break;
            }
        } catch (Exception e){
            System.out.println("输入有误:" + e.toString());
        }
    }
}

这样便解决了代码错误的问题,但工作过的伙伴应该知道,业务总是在不断变化的,如果现在需要你做出一个windows的计算机程序呢,
或许你想着是直接将代码复制过去,改动不大,但这并不是好的习惯,当系统代码的重复度过高,后期维护将是一场灾难。所以接下来我们应该将程序拆分,封装。

二、业务的封装

想想看,之前写的这些代码,有哪些是和控制台无关的,只是和计算器有关?我们可以让业务逻辑与界面逻辑分开,让他们之间的耦合度下降,只有分离开,才可以达到容易维护与拓展。
1、运算类

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

在这里插入图片描述
将上述红框代码改为如下

  Scanner sc = new Scanner(System.in);
            System.out.println("请输入数字A: ");
            double numberA = Double.parseDouble(sc.nextLine());
            System.out.println("请输入运算符号(+、-、*、 /):");
            String sign = sc.nextLine();
            System.out.println("请输入数字B:");
            double numberB = Double.parseDouble(sc.nextLine());
            
            double result = Operation.getResult(numberA, numberB, sign);

这样就把业务和界面分离了。
目前只用了面向对象特性的其中一种:封装,还有多态和继承
我们接着看,如果现在新增了一个需求,我们需要添加一个指数运算,那很简单啊,直接在Operation类switch加一个分支就好了。
在这里插入图片描述
这样会带来一个问题,你只是添加一个指数运算,却要让加减乘除都参与编译,如果你一不小心把这个公共方法该坏了,比如把加改成了减,那岂不糟糕了。打个比方,如果你在维护一个薪资管理系统,原本只有技术人员(月薪)、销售人员(底薪+提成)、老板(年薪+股份)三种算法,现在需要添加一个兼职工作人员(时薪的算法)。按照之前的写法,公司必须把原本的三种运算方法代码都给你,让你修改,如果你不小心把自己的薪资构成改了,那…
所以,我们需要将加减乘除运算分离,修改一个不影响另外几个
利用继承和多态
运算类

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

加减乘除类

public class Add extends Operation{
    @Override
    public double getResult(double numberA, double numberB) {
        return numberA + numberB;
    }
}
public class Sub extends Operation{
    @Override
    public double getResult(double numberA, double numberB) {
        return numberA - numberB;
    }
}

以此类推。
这样,如果要修改任何一个算法,就不需要提供其他算法的代码了。但问题来了,我们如何让计算器知道我是希望用哪个算法呢?

三、简单工厂模式

上面的问题,也就是实例化哪个对象的问题,我们可以考虑用个单独的类来做这个创造实例的过程,这就是工厂
下面来写一个简单的工厂类
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;
    }
}

界面代码

Operation operate = OperationFactory.createOperate(sign);
double result = operate.getResult(numberA, numberB);

有了工厂模式,如果后续需要修改加法运算,只需要改Add类,如果需要添加其他运算,只需要增加相应的子类,且在工厂中添加对应的分支。
以上的例子比较简单,重点在于理解工厂模式,以及为什么用工厂模式,这个在项目中的维护至关重要。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮春二十四

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值