计算器代码
请用C++、Java、C#、或VB.NET任意的一种面向对象语言实现一个计算器控制台应用程序,要求输入两个数和运算符号,得到结果。
1、最简(yú)单(chǔn)的实现
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入数字A:");
String A = scan.nextLine();
System.out.println("请输入运算符号(+、-、*、/):");
String B = scan.nextLine();
System.out.println("请输入数字B:");
String C = scan.nextLine();
String D = "";
if (B.equals("+")) {
D = String.valueOf(Double.parseDouble(A) + Double.parseDouble(C));
}
if (B.equals("-")) {
D = String.valueOf(Double.parseDouble(A) - Double.parseDouble(C));
}
if (B.equals("*")) {
D = String.valueOf(Double.parseDouble(A) * Double.parseDouble(C));
}
if (B.equals("/")) {
D = String.valueOf(Double.parseDouble(A) / Double.parseDouble(C));
}
System.out.println("结果是:" + D);
}
}
点评:
- 1 命名不规范
- 2 判断分支这样写意味着每个条件都要判断,计算机做了三次无用功
- 3 未考虑程序异常情况
- 3.1 输入非法数字(java.lang.NumberFormatException)
- 3.2 非法运算符(跳过所有判断分支,输出空字符串)
- 3.3 除数为0(java.lang.ArithmeticException: / by zero)
思考
- 改进程序,解决上述隐患与不规范
2、代码规范化
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
Scanner scan = new Scanner(System.in);
System.out.println("请输入数字A:");
String strNumberA = scan.nextLine();
System.out.println("请输入运算符号(+、-、*、/):");
String strOperate = scan.nextLine();
System.out.println("请输入数字B:");
String strNumberB = scan.nextLine();
String strResult = "";
switch (strOperate) {
case "+":
strResult = String.valueOf(Double.parseDouble(strNumberA) + Double.parseDouble(strNumberB));
break;
case "-":
strResult = String.valueOf(Double.parseDouble(strNumberA) - Double.parseDouble(strNumberB));
break;
case "*":
strResult = String.valueOf(Double.parseDouble(strNumberA) * Double.parseDouble(strNumberB));
break;
case "/":
if (Double.parseDouble(strNumberB) != 0) {
strResult = String.valueOf(Double.parseDouble(strNumberA) / Double.parseDouble(strNumberB));
} else {
strResult = "除数不能为0!";
}
break;
default:
strResult = "非法运算符!";
}
System.out.println("结果是:" + strResult);
} catch (Exception e) {
System.out.println("您的输入有误:" + e.getMessage());
}
}
}
点评
- 1 没有体现面向对象
- 2 可以考虑使用简单工厂模式
思考
- 如何使程序变得可维护、可复用、可拓展、灵活性好?
- 通过封装、继承、多态把程序的耦合度降低
- 用设计模式使得程序更加的灵活,容易修改,并且易于复用
3、面向对象之封装
Operation运算类
public class Operation {
public static String getResult(double numberA, double numberB, String operate) {
String result = "";
switch (operate) {
case "+":
result = String.valueOf(numberA + numberB);
break;
case "-":
result = String.valueOf(numberA - numberB);
break;
case "*":
result = String.valueOf(numberA * numberB);
break;
case "/":
if (numberB != 0) {
result = String.valueOf(numberA / numberB);
} else {
result = "除数不能为0!";
}
break;
default:
result = "非法运算符!";
}
return result;
}
}
客户端代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
Scanner scan = new Scanner(System.in);
System.out.println("请输入数字A:");
String strNumberA = scan.nextLine();
System.out.println("请输入运算符号(+、-、*、/):");
String strOperate = scan.nextLine();
System.out.println("请输入数字B:");
String strNumberB = scan.nextLine();
String strResult = Operation.getResult(
Double.parseDouble(strNumberA),
Double.parseDouble(strNumberB),
strOperate);
System.out.println("结果是:" + strResult);
} catch (Exception e) {
System.out.println("您的输入有误:" + e.getMessage());
}
}
}
点评
- 完全把业务和界面分离了
- 运算类(Operation) 可复用
- 只用到了面向对象的封装
思考
- 如何将面向对象的另外两大特征(继承、多态)应用在程序中?
4、面向对象之继承、多态+简单工厂模式
Operation运算类
public abstract class Operation {
protected double numberA;
protected double numberB;
public abstract String getResult();
}
加减乘除类
public class OperationAdd extends Operation {
@Override
public String getResult() {
return String.valueOf(numberA + numberB);
}
}
public class OperationSub extends Operation {
@Override
public String getResult() {
return String.valueOf(numberA - numberB);
}
}
public class OperationMul extends Operation {
@Override
public String getResult() {
return String.valueOf(numberA * numberB);
}
}
public class OperationDiv extends Operation {
@Override
public String getResult() {
if (numberB == 0) {
return "除数不能为0";
}
return String.valueOf(numberA / numberB);
}
}
运算工厂类
public class OperationFactory {
public static Operation create(String operate) throws Exception {
Operation oper = null;
switch (operate) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
throw new Exception("非法运算符");
}
return oper;
}
}
客户端核心代码
Operation oper = OperationFactory.create(strOperate);
oper.numberA = Double.parseDouble(strNumberA);
oper.numberB = Double.parseDouble(strNumberB);
System.out.println("结果是:" + oper.getResult());
点评
- 运算父类及子类、运算工厂类封装完成,可复用性高
- 如果只修改具体的某一运算(如:乘法运算),只需要修改该类就可以了。减轻了耦合度。同时也减轻了编译负担(对比1、2、3的代码)。可维护性好。
- 如果要增加运算。则只需要增加新的运算类,以及在运算工厂类中增加该运算的判断。逻辑清晰明了。可拓展性好,灵活性好。
- 如果修改界面,运算相关的类一个也不用改。