面试受挫
即将毕业的小菜在面试时要求写出计算器控制台程序,以下为小菜的代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字A");
double A = sc.nextDouble();
System.out.println("请输入一个运算符");
char op = sc.next().charAt(0);
System.out.println("请输入一个数字B");
double B = sc.nextDouble();
double res = 0;
if('+' == op)res = A + B;
else if('-' == op)res = A - B;
else if('*' == op)res = A * B;
else if ('/' == op)res = A / B;
System.out.println("结果是:" + res);
}
}
初学者代码毛病:
-
命名不规范:使用A,B来命名
-
if做了好几次无用功
-
没有处理除数为0的情况
代码规范
import java.util.Scanner;
public class SimpleFactory02 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字A");
String numA = sc.next();
System.out.println("请输入一个运算符(+,-,*,/):");
String strOperator = sc.next();
System.out.println("请输入一个数字B");
String numB = sc.next();
String res = "";
try{
switch (strOperator){
case "+":res = String.valueOf(Double.parseDouble(numA) + Double.parseDouble(numB)) ;break;
case "-":res = String.valueOf(Double.parseDouble(numA) - Double.parseDouble(numB));break;
case "*":res = String.valueOf(Double.parseDouble(numA) * Double.parseDouble(numB));break;
case "/":{
if(!"0".equals(numB))res = String.valueOf(Double.parseDouble(numA) / Double.parseDouble(numB));
else res = "除数不能为0";
break;
}
}
System.out.println("结果是:" + res);
}catch (Exception e){
e.printStackTrace();
}
}
}
以上代码实现计算器是没有问题的,但是否就真的好呢?
面向对象要达到的特点
-
可维护
-
可复用
-
可扩展
-
灵活性好
面向对象的好处
-
通过封装,继承,多态来降低耦合
-
用设计模式使程序更加灵活,容易修改,易于复用
业务的封装
-
Operator运算类
package SimpleFactory03;
public class Operator {
public static double getResult(double numA,double numB,String operator){
double res = 0;
switch (operator){
case "+": res = numA + numB;break;
case "-": res = numA - numB;break;
case "*": res = numA * numB;break;
case "/": res = numA / numB;break;
}
return res;
}
}
-
客户端代码
package SimpleFactory03;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字A");
String numA = sc.next();
System.out.println("请输入一个运算符(+,-,*,/):");
String strOperator = sc.next();
System.out.println("请输入一个数字B");
String numB = sc.next();
String result = String.valueOf(
Operator.getResult(Double.parseDouble(numA), Double.parseDouble(numB), strOperator)) ;
System.out.println("结果是:" + result);
}catch (Exception e){
e.printStackTrace();
}
}
}
这样在别的地方也可以复用Operator运算类
紧耦合 vs 松耦合
上面的Operator运算类
虽然已经满足我们的需求了,但如果要加sqrt()运算
呢?
-
你的回答可能是在
Operator运算类
的switch(){ case: }
中再加case
,这会使得我想要添加sqrt()运算
,其他的运算却也要参加编译,这是我们不希望的
继承,多态解决
-
Operator运算类
package SimpleFactory04;
public class Operation {
private double numA;
private double numB;
public double getResult(){
double result = 0;
return result;
}
public double getNumA() {
return numA;
}
public void setNumA(double numA) {
this.numA = numA;
}
public double getNumB() {
return numB;
}
public void setNumB(double numB) {
this.numB = numB;
}
}
-
加减乘除类(Operator运算类的子类)
package SimpleFactory04;
// 实现加法,继承运算类
public class OperationAdd extends Operation{
@Override
public double getResult() {
double result = this.getNumA() + this.getNumB();
return result;
}
}
// 减法
public class OperationSub extends Operation{
@Override
public double getResult(){
double result = this.getNumA() - this.getNumB();
return result;
}
}
// 乘
public class OperationMul extends Operation{
@Override
public double getResult(){
double result = this.getNumA() * this.getNumB();
return result;
}
}
// 除
public class OperationDiv extends Operation{
@Override
public double getResult(){
double numA = this.getNumA(),numB = this.getNumB();
if(numB == 0)throw new RuntimeException("除数不能为0");
return numA / numB;
}
}
-
简单运算工厂类
package SimpleFactory04;
public class OperationFactory {
public static Operation createOperate(String strOperate){
Operation operation = null;
switch (strOperate){
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
}
return operation;
}
}
-
客户端代码
package SimpleFactory04;
public class Client {
public static void main(String[] args) {
Operation operation = OperationFactory.createOperate("/");
operation.setNumA(9);
operation.setNumB(2);
double result = operation.getResult();
System.out.println(result);
}
}
这样运算类就与运算方法解耦合了,添加其他的运算,只需继承运算类实现对应方法即可。