1.任務(wù)
使用面向?qū)ο笏枷雽?shí)現(xiàn)計(jì)算器程序,要求輸入兩個(gè)數(shù)字和運(yùn)算符得到結(jié)果鹤竭;
2.初步實(shí)現(xiàn)
public class Calc {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("請(qǐng)輸入數(shù)字A:");
Double A = scanner.nextDouble();
System.out.print("請(qǐng)輸入數(shù)字運(yùn)算符(+挂脑、-藕漱、*、/):");
String C = scanner.next();
System.out.print("請(qǐng)輸入數(shù)字B:");
Double B = scanner.nextDouble();
if ("+".equals(sign)) {
System.out.println("結(jié)果:" + (A + B));
}
if ("-".equals(sign)) {
System.out.println("結(jié)果:" + (A - B));
}
if ("*".equals(sign)) {
System.out.println("結(jié)果:" + (A * B));
}
if ("/".equals(sign)) {
System.out.println("結(jié)果:" + (A / B));
}
}
}
代碼看似功能實(shí)現(xiàn)但是還是存在許多問(wèn)題
存在問(wèn)題
- 變量命名不規(guī)范
Double A = scanner.nextDouble();
String C = scanner.next();
Double B = scanner.nextDouble();
- 這樣寫(xiě)分支判斷會(huì)導(dǎo)致代碼會(huì)判斷每一個(gè)分支
if ("+".equals(C)) {
System.out.println("結(jié)果:" + (A + B));
}
if ("-".equals(C)) {
System.out.println("結(jié)果:" + (A - B));
}
if ("*".equals(C)) {
System.out.println("結(jié)果:" + (A * B));
}
if ("/".equals(C)) {
System.out.println("結(jié)果:" + (A / B));
}
- 沒(méi)有進(jìn)行輸入驗(yàn)證崭闲,除數(shù)不能為0
3.代碼優(yōu)化
public class Calc {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.print("請(qǐng)輸入數(shù)字A:");
Double numberA = scanner.nextDouble();
System.out.print("請(qǐng)輸入數(shù)字運(yùn)算符(+肋联、-、*刁俭、/):");
String sign = scanner.next();
System.out.print("請(qǐng)輸入數(shù)字B:");
Double numberB = scanner.nextDouble();
switch (sign) {
case "+":
System.out.println("結(jié)果:" + (numberA + numberB));
break;
case "-":
System.out.println("結(jié)果:" + (numberA - numberB));
break;
case "*":
System.out.println("結(jié)果:" + (numberA * numberB));
break;
case "/":
if (numberB == 0) {
System.out.println("除數(shù)不能為0");
break;
}
System.out.println("結(jié)果:" + (numberA / numberB));
break;
}
} catch (Exception e) {
System.out.println("您的輸入有誤:" + e.getMessage());
}
}
}
優(yōu)化之后的代碼質(zhì)量明顯優(yōu)于之前的代碼橄仍,但還是不易于維護(hù)和擴(kuò)展。此時(shí)我們需要對(duì)代碼的業(yè)務(wù)進(jìn)行封裝薄翅,也就是說(shuō)讓業(yè)務(wù)邏輯跟業(yè)務(wù)交互分開(kāi)沙兰。讓他們之間的耦合度下降。
4.業(yè)務(wù)的封裝
- 業(yè)務(wù)代碼
public class Operation {
public static Double getResult(Double numberA, Double numberB, String sign) throws Exception {
switch (sign) {
case "+":
return numberA + numberB;
case "-":
return numberA - numberB;
case "*":
return numberA * numberB;
case "/":
if (numberB == 0) {
throw new Exception("除數(shù)不能為0");
}
return numberA / numberB;
}
throw new Exception("符號(hào)輸入錯(cuò)誤");
}
}
- 交互代碼
public class Calc {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.print("請(qǐng)輸入數(shù)字A:");
Double numberA = scanner.nextDouble();
System.out.print("請(qǐng)輸入數(shù)字運(yùn)算符(+翘魄、-鼎天、*、/):");
String sign = scanner.next();
System.out.print("請(qǐng)輸入數(shù)字B:");
Double numberB = scanner.nextDouble();
System.out.println(Operation.getResult(numberA, numberB, sign));
} catch (Exception e) {
System.out.println("您的輸入有誤:" + e.getMessage());
}
}
}
封裝之后代碼清爽了許多暑竟,但是依然存在一些問(wèn)題斋射;假如現(xiàn)在新增需求在原有的基礎(chǔ)上新增一個(gè)平方的計(jì)算方式,就意味著需要在原來(lái)的代碼上進(jìn)行修改并且有可能會(huì)影響到其他計(jì)算類型〉纾現(xiàn)在我們使用簡(jiǎn)單工廠模式修改代碼罗岖。
5.簡(jiǎn)單工廠模式
- Operation抽象類
@Data
public abstract class Operation {
private Double numberA;
private Double numberB;
public abstract Double getResult() throws Exception;
}
注:@Data是Lombok封裝的注解主要功能是生成setter,getter方法
- 加
public class Plus extends Operation {
@Override
public Double getResult() throws Exception {
return getNumberA() + getNumberB();
}
}
- 減
public class Subtract extends Operation {
@Override
public Double getResult() throws Exception {
return getNumberA() - getNumberB();
}
}
- 乘
public class Multi extends Operation {
@Override
public Double getResult() throws Exception {
return getNumberA() * getNumberB();
}
}
- 除
public class Div extends Operation {
@Override
public Double getResult() throws Exception {
if (Objects.isNull(getNumberB()) || getNumberB() == 0) {
throw new Exception("除數(shù)不能為0");
}
return getNumberA() / getNumberB();
}
}
- 平方
public class Square extends Operation {
@Override
public Double getResult() {
return getNumberA() * getNumberA();
}
}
- 工廠類
public class OperationFactory {
public static Operation createOperation(String sign) throws Exception {
switch (sign) {
case "+":
return new Plus();
case "-":
return new Subtract();
case "*":
return new Multi();
case "/":
return new Div();
case "^2":
return new Square();
}
throw new Exception("符號(hào)輸入錯(cuò)誤");
}
}
只需要符號(hào)工廠類就可以實(shí)例化出合適的對(duì)象腹躁。通過(guò)多態(tài)桑包,父類引用指向子類對(duì)象返回子類計(jì)算得出的結(jié)果。
- 交互代碼
Operation operation = OperationFactory.createOperation(sign);
operation.setNumberA(numberA);
operation.setNumberB(numberB);
System.out.println(operation.getResult());
修改之后的代碼比之前的代碼更具有擴(kuò)展性纺非,也更加便于維護(hù)哑了。后續(xù)如果需要新增一些計(jì)算類型只需要繼承Operation抽象類實(shí)現(xiàn)getResult方法即可。