2017年4月20日 星期四

ATM 05

完整的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;
}
因此我們得寫成這樣,多了一個區域變數

至此,整體邏輯看起來都還行了

下一篇就來整理程式碼吧

沒有留言:

張貼留言