案例
在面试时,面试官让你通过面对对象语言,用Java实现计算器控制台程序,要求输入两个数和运算符号,得出结果。大家可能想到是如下:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入任意数1");
double numberA = scanner.nextDouble();
System.out.println("请输入任意数2");
double numberB = scanner.nextDouble();
System.out.println("请选择运算符(+、-、*、/)");
String operation = scanner.next();
double result = 0L;
switch (operation) {
case "+" :
result = numberA + numberB;
break;
case "-" :
result = numberA - numberB;
break;
case "*" :
result = numberA * numberB;
break;
case "/" :
result = numberA / numberB;
break;
default:
break;
}
System.out.println("结果:" + result);
scanner.close();
}
上面的代码确实能够满足面试所需求的,但是你觉得就真的这么简单吗。
写出上列代码只能说明你有一定的代码基础能力,如果是刚毕业能写出来还算OK,但是如果你已经工作一年以上还写出这种代码,只能说平常确实没有进行过学习。
通过这道题目可以考验你对Java的封装、继承、多态、设计模式的理解。
封装
分离业务逻辑和界面逻辑,降低耦合度,实现易维护、易扩展
Operation运算类
public class Operation {
public static double GetResult(double numberA, double numberB, String operation) {
double result = 0L;
switch (operation) {
case "+" :
result = numberA + numberB;
break;
case "-" :
result = numberA - numberB;
break;
case "*" :
result = numberA * numberB;
break;
case "/" :
result = numberA / numberB;
break;
default:
break;
}
return result;
}
}
客户端代码
@SpringBootTest
class ProgramTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入任意数1");
double numberA = scanner.nextDouble();
System.out.println("请输入任意数2");
double numberB = scanner.nextDouble();
System.out.println("请选择运算符(+、-、*、/)");
String operation = scanner.next();
double result = Operation.GetResult(numberA, numberB, operation);
System.out.println("结果:" + result);
scanner.close();
}
}
这样就将业务与页面分离开,后面其他程序需要用到计算业务,直接复用Operation就可。
但是依旧达不到灵活的可修改和可扩展,比如现在需要增加一个开根运算,那只能改Operation,在switch中增加一个分支,在复杂业务中,改动原有逻辑有可能会出现问题。
要想实现灵活的可修改和可扩展,就需要使用到继承和多态
继承、多态
Operation 计算器的父类
public abstract class Operation {
private double numberA;
private double numberB;
public abstract double getResult();
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
}
加法
public class Add extends Operation {
@Override
public double getResult() {
return getNumberA() + getNumberB();
}
}
减法
public class Sub extends Operation {
@Override
public double getResult() {
return getNumberA() - getNumberB();
}
}
加减乘除写成运算类的子类,继承运算类后,重写GetResult()方法,这样修改任何一个算法,都不需要提供其他算法的代码了,但问题来了,如何让计算器知道我是希望使用哪一种算法呢?
简单工厂模式
简单运算工厂类
public class OptionerFactory {
public static Operation createOperation(String operation) {
Operation oper = null;
switch (operation) {
case "+":
oper = new Add();
break;
case "-":
oper = new Sub();
break;
}
return oper;
}
}
只需要输入运算符号,工厂就实例化出合适的对象,通过多态,返回父类的方式实现了计算器的结果
客户端代码
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入任意数1");
double numberA = scanner.nextDouble();
System.out.println("请输入任意数2");
double numberB = scanner.nextDouble();
System.out.println("请选择运算符(+、-、*、/)");
String oper = scanner.next();
Operation operation = OptionerFactory.createOperation(oper);
operation.setNumberA(numberA);
operation.setNumberB(numberB);
double result = operation.getResult();
System.out.println("结果:"+result);
}
测试结果
总结
题目很简单,就像在学校解数学题一样,解法有很多种,但是大部分人只会最简单的一种,你能写出多种解法,说明你对这方面有深入学习过。而面试官要考验的就是这个。