完整的ATM非常獨特,事實上,它需要能夠不斷運行
再者我們一直沒有對使用者回應操作完畢的狀態,因此我們將盡速模擬完成
while (true) {
System.out.println("請輸入帳號");
String userID = sc.nextLine();
System.out.println("請輸入密碼");
String userPassword = sc.nextLine();
ResultAccount account = DataBase.find(userID, userPassword);
if (account.found) {
// ...
} else {
System.out.println("帳號不存在或是密碼輸入錯誤");
}
}
為了讓ATM能不斷運行而加上了無窮迴圈
再者我們必須在找不到帳戶時讓使用者明白他們遇上了什麼問題
再來讓DataBase實例化
static DataBase db = new DataBase();
當然,所有存取方式都得改變
double balance = (double) m.invoke(db.Users.get(account.location));
System.out.println("剩餘 " + balance + "元");
接著我們讓這些方法回傳現在剩餘多少錢,然後告知使用者
再來因為Account實在沒有存在User中的必要,所以我暫時將它移出
接著我們發現一個問題,我們把流程混入了應當無副作用的Account Method: userWithdraw中
所以我們把流程移到高一層次的User.withdraw之中,定義如下
double userWithdraw(int amountOfWithdraw) throws BalanceException {
if (amountOfWithdraw < balance) {
balance -= amountOfWithdraw;
log.AddWithdrawLog(amountOfWithdraw);
return balance;
} else {
throw new BalanceException();
}
}
使用則是
try {
return ac.userWithdraw(amountOfWithdraw);
} catch (BalanceException e) {
System.out.println("操作失敗,餘額不足");
} finally {
return -1;
}
很不幸的,由於語言的限制,我們必須回傳一個值
然後我們舒爽的按下執行測試,很不錯,又出錯了呢...
為什麼呢?它說我們必須為拋出例外的程式加上try區塊,否則我們得拋出例外,我們得處理這個事實
public void withdrawTest() {
User u = new User("", "", 50000);
try {
u.ac.userWithdraw(10000);
} catch (BalanceException e) {
// 我們不需要在這處理錯誤
} finally {
Assert.assertEquals(40000, u.ac.balance, 0.0000001);
}
}
變成這樣了
而且我們還要處理一個事實,就是在測試中要測試提領失敗的情況(但不是在上面的測試)
public void withdrawFailTest() {
User u = new User("", "", 50000);
double excepted = -10000;
try {
u.ac.userWithdraw(60000);
} catch (BalanceException e) {
excepted = 50000;
} finally {
Assert.assertEquals(excepted, u.ac.balance, 0.0000001);
}
}
我們得說清楚,這個測試是指提款失敗時
接著,我們實際執行了一下,嗚!我提50000元之後,它說
操作失敗,餘額不足
剩餘 -1.0元
...好像不大對呢(廢話,一整個都不對啊)
double balance = ac.balance;
try {
balance = ac.userWithdraw(amountOfWithdraw);
return balance;
} catch (BalanceException e) {
System.out.println("操作失敗,餘額不足");
} finally {
return balance;
}
因此我們得寫成這樣,多了一個區域變數
至此,整體邏輯看起來都還行了
下一篇就來整理程式碼吧
沒有留言:
張貼留言