前言
假如目前有一个需求,需要你利用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.客户端不用关心服务端对象的创建过程
原理
抽象产品:通过抽象类或者接口定义产品的规范,就是在抽象类或者接口中写主要的特征或者功能点
具体产品:实现接口的实现类或者继承接口的子类
具体工厂:提供创建产品的静态方法。消费者调用该方法来获取产品
优缺点
优点
封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。
缺点
增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。