简单的工厂设计模式
记得在刚开始学习java时候,书上有这么一个例子:用Java实现一个计算器功能。
然后自己当时代码如下(不考虑输入的符号等):
System.out.println("请输入第一个数:"); Scanner in = new Scanner(System.in); String str1 = in.next(); System.out.println("请输入运算符号:"); String flag = in.next(); System.out.println("请输入第二个数:"); String str2 = in.next(); if(flag.equals("-")){ System.out.println(Double.parseDouble(str1) - Double.parseDouble(str2)); } if(flag.equals("/")){ if (Double.parseDouble(str2) == 0) { throw new Exception("除数不能为0!"); }else { System.out.println(Double.parseDouble(str1) / Double.parseDouble(str2)); } } if(flag.equals("*")){ System.out.println(Double.parseDouble(str1) * Double.parseDouble(str2)); } if(flag.equals("+")){ System.out.println(Double.parseDouble(str1) + Double.parseDouble(str2)); } }
不输入一些怪异的特殊符号运行:
功能大致上没有问题,但是现在看来也觉得没有什么大的问题。
但是考虑到扩展问题,而且现实中并不是一些加减乘除的算法。还有一些特殊比如平方运算,开方,指数,对数等!
这个时候我们需要怎么写?
我们去写的这个后面添加一个if分支,然后每次在进行扩展。这样子也可以实现,但是每次在原有的代码上继续写,每次添加运算运算符。 输入输出代码混在一起,很难维护和扩展。
这时候我们改怎么办?
我们想办法用上面向对象的特征,然后将输入输出和运算进行拆分。
首先我们定义一个参数接口:
public interface Param { double getResult( double d1 ,double d2); }
然后定义需要实现的各个运算类型的对象类
Add
public class Add implements Param { @Override public double getResult(double d1 ,double d2){ double result = d1 + d2 ; return result; } }
Division
public class Division implements Param { @Override public double getResult(double d1 ,double d2){ if (d2 == 0) try { throw new Exception(" is not 0 "); } catch (Exception e) { e.printStackTrace(); } double result = d1 / d2 ; return result; } }
Multi
public class Multi implements Param { @Override public double getResult(double d1 ,double d2){ double result = d1 * d2 ; return result; } }
Subtraction
public class Subtraction implements Param { @Override public double getResult(double d1 ,double d2){ double result = d1 - d2 ; return result; } }
定义一个实现的工厂去处理选择那个对象,然后去实现那个方法,返回哪个结果运算。
最后调用
public static void main(String args []){ System.out.println("请输入第一个数:"); Scanner in = new Scanner(System.in); double d1 = in.nextDouble(); System.out.println("请输入运算符号:"); String flag = in.next(); System.out.println("请输入第二个数:"); double d2 = in.nextDouble(); Param param = null; /* 根据运算符不一致,创建不同的对象 , 目的是为了创建对象 */ switch (flag) { case "+": param = new Add(); break; case "-": param = new Subtraction(); break; case "/": param = new Division(); break; case "*": param = new Multi(); break; } double result = param.getResult( d1 , d2 ); System.out.println(result); }
工厂的目的是为了创建对象 , 根据子类去实例化哪个对象。
这样做的目的是为了解耦合,让代码的耦合度降低,达到易于扩展的目的。
这样子如果我们有别的运算,我们只需新建一个新的运算类,然后在工厂里面进行对象创建即可。