📄 simulatedbank.java
字号:
/* * ATM Example system - file SimulatedBank.java * * copyright (c) 2001 - Russell C. Bjork * */ package simulation;import banking.AccountInformation;import banking.Balances;import banking.Card;import banking.Message;import banking.Money;import banking.Status;/** Simulation of the bank. A set of simulated accounts is initalized at startup. */public class SimulatedBank{ /** Simulate the handling of a message * * @param message the message to send * @param balances (out) balances in customer's account as reported * by bank * @return status code returned by bank */ public Status handleMessage(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); if (cardNumber < 1 || cardNumber > PIN.length) return new Failure("Invalid card"); if (message.getPIN() != PIN [ cardNumber ] ) return new InvalidPIN(); switch(message.getMessageCode()) { case Message.WITHDRAWAL: return withdrawal(message, balances); case Message.INITIATE_DEPOSIT: return initiateDeposit(message); case Message.COMPLETE_DEPOSIT: return completeDeposit(message, balances); case Message.TRANSFER: return transfer(message, balances); case Message.INQUIRY: return inquiry(message, balances); } // Need to keep compiler happy return null; } /** Simulate processing of a withdrawal * * @param message the message describing the withdrawal requested * @param balances (out) balances in account after withdrawal * @return status code derived from current values */ private Status withdrawal(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getFromAccount() ]; if (accountNumber == 0) return new Failure("Invalid account type"); Money amount = message.getAmount(); Money limitRemaining = new Money(DAILY_WITHDRAWAL_LIMIT); limitRemaining.subtract(WITHDRAWALS_TODAY[ cardNumber ]); if (! amount.lessEqual(limitRemaining)) return new Failure("Daily withdrawal limit exceeded"); if (! amount.lessEqual(AVAILABLE_BALANCE [ accountNumber ])) return new Failure("Insufficient available balance"); // Update withdrawals today and account balances once we know everything is // OK WITHDRAWALS_TODAY [ cardNumber ].add(amount); BALANCE [ accountNumber ].subtract(amount); AVAILABLE_BALANCE [ accountNumber ].subtract(amount); // Return updated balances balances.setBalances(BALANCE [ accountNumber ], AVAILABLE_BALANCE [ accountNumber ]); return new Success(); } /** Simulate initiation of a deposit. At this point, the bank only approves * the validity of the deposit - no changes to the records are made until * the envelope is actually inserted * * @param message the message describing the deposit requested * @return status code derived from current values */ private Status initiateDeposit(Message message) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getToAccount() ]; if (accountNumber == 0) return new Failure("Invalid account type"); // Don't update anything yet return new Success(); } /** Simulate completion of a deposit * * @param message the message describing the deposit requested * @param balances (out) balances (not updated until completed) * @return status code - must always be success in this case */ private Status completeDeposit(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getToAccount() ]; if (accountNumber == 0) return new Failure("Invalid account type"); // Now we can update the balance Money amount = message.getAmount(); BALANCE [ accountNumber ].add(amount); // Return updated balances balances.setBalances(BALANCE [ accountNumber ], AVAILABLE_BALANCE [ accountNumber ]); return new Success(); } /** Simulate processing of a transfer * * @param message the message describing the transfer requested * @param balances (out) balances in "to" account after transfer * @return status code derived from current values */ private Status transfer(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int fromAccountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getFromAccount() ]; if (fromAccountNumber == 0) return new Failure("Invalid from account type"); int toAccountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getToAccount() ]; if (toAccountNumber == 0) return new Failure("Invalid to account type"); if (fromAccountNumber == toAccountNumber) return new Failure("Can't transfer money from\n" + "an account to itself"); Money amount = message.getAmount(); if (! amount.lessEqual(AVAILABLE_BALANCE [ fromAccountNumber ])) return new Failure("Insufficient available balance"); // Update account balances once we know everything is OK BALANCE [ fromAccountNumber ].subtract(amount); AVAILABLE_BALANCE [ fromAccountNumber ].subtract(amount); BALANCE [ toAccountNumber ].add(amount); AVAILABLE_BALANCE [ toAccountNumber ].add(amount); // Return updated balances balances.setBalances(BALANCE [ toAccountNumber ], AVAILABLE_BALANCE [ toAccountNumber ]); return new Success(); } /** Simulate processing of an inquiry * * @param message the message describing the inquiry requested * @param balances (out) balances in account * @return status code derived from current values */ private Status inquiry(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER [ cardNumber ] [ message.getFromAccount() ]; if (accountNumber == 0) return new Failure("Invalid account type"); // Return requested balances balances.setBalances(BALANCE [ accountNumber ], AVAILABLE_BALANCE [ accountNumber ]); return new Success(); } /** Representation for status of a transaction that succeeded */ private static class Success extends Status { public boolean isSuccess() { return true; } public boolean isInvalidPIN() { return false; } public String getMessage() { return null; } } /** Representation for status of a transaction that failed (for reason other than * invalid PIN) */ private static class Failure extends Status { /** Constructor * * @param message description of the failure */ public Failure(String message) { this.message = message; } public boolean isSuccess() { return false; } public boolean isInvalidPIN() { return false; } public String getMessage() { return message; } private String message; } /** Representation for status of a transaction that failed due to an invalid PIN */ private static class InvalidPIN extends Failure { /** Constructor * * @param message description of the failure */ public InvalidPIN() { super("Invalid PIN"); } public boolean isInvalidPIN() { return true; } } /** PIN for each card. (Valid card numbers start with 1) */ private static final int PIN [] = { 0, // dummy for nonexistent card 0 42, 1234 }; /** Array of account numbers associated with each card. For each card, * there can be three different types of account, which correspond to * the names in class AccountInformation. 0 means no account of this * type. (Valid card numbers start with 1) */ private static final int ACCOUNT_NUMBER [] [] = { { 0, 0, 0 }, // dummies for nonexistent card 0 { 1, 2, 0 }, { 1, 0, 3 } }; /** Withdrawals so far today on each card. (Valid card numbers start with 1) */ private static Money WITHDRAWALS_TODAY [] = { new Money(0), // dummy for nonexistent card 0 new Money(0), new Money(0) }; /** Maximum daily withdrawal limit for any one card. */ private static final Money DAILY_WITHDRAWAL_LIMIT = new Money(300); /** Balance for each account (will change as program runs, hence not a * static final. */ private Money BALANCE [] = { new Money(0), // dummy for nonexistent account 0 new Money(100), new Money(1000), new Money(5000) }; /** Available alance for each account (will change as program runs, hence * not a static final. */ private Money AVAILABLE_BALANCE [] = { new Money(0), // dummy for nonexistent account 0 new Money(100), new Money(1000), new Money(5000) };}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -