Source code class ATM:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class ATM { private boolean userAuthenticated; // whether user is authenticated private int currentAccountNumber; // current user's account number private Screen screen; // ATM's screen private Keypad keypad; // ATM's keypad private CashDispenser cashDispenser; // ATM's cash dispenser private DepositSlot depositSlot; // ATM's deposit slot private BankDatabase bankDatabase; // account information database // constants corresponding to main menu options private static final int BALANCE_INQUIRY = 1; private static final int WITHDRAWAL = 2; private static final int DEPOSIT = 3; private static final int EXIT = 4; // no-argument ATM constructor initializes instance variables public ATM(){ userAuthenticated = false; // user is not authenticated to start currentAccountNumber = 0; // no current account number to start screen = new Screen(); // create screen keypad = new Keypad(); // create keypad cashDispenser = new CashDispenser(); // create cash dispenser depositSlot = new DepositSlot(); // create deposit slot bankDatabase = new BankDatabase(); // create account info database } // end no argument ATM constructor // start ATM public void run(){ // welcome and authenticate user; perform transactions while(true){ // loop while user is not yet authenticated while(!userAuthenticated){ screen.displayMessageLine("\nWelcome!"); authenticateUser(); // authenticate user } // end while performTransactions(); // user is now authenticated userAuthenticated = false; // reset before next ATM session currentAccountNumber = 0; // reset before next ATM session screen.displayMessageLine("\nThank You!\nGoodbye!"); } // end while } // end method run // attempts to authenticate user against database private void authenticateUser(){ screen.displayMessage("\nPlease enter your account number : "); int accountNumber = keypad.getInput(); // input account number screen.displayMessage("\nEnter your PIN : "); // prompt for PIN int pin = keypad.getInput(); // input PIN // set userAuthenticated to boolean value returned by database userAuthenticated = bankDatabase.authenticateUser(accountNumber, pin); // check whether authentication succeeded if(userAuthenticated){ currentAccountNumber = accountNumber; // save user's account } // end if else{ screen.displayMessageLine("Invalid Account Number or PIN."); screen.displayMessageLine("Please Try Again."); } } // end method authenticateUser // display the main menu and perform transactions private void performTransactions(){ // local variable to store transaction currently being processed Transaction currentTransaction = null; boolean userExited = false; // user has not chosen to exit // loop while user has not chosen option to exit system while(!userExited){ // show main menu and get user selection int mainMenuSelection = displayMainMenu(); // decide how to proceed based on user's menu selection switch(mainMenuSelection){ // user choose to perform one of three transaction types case BALANCE_INQUIRY : case WITHDRAWAL : case DEPOSIT : // initialize as new object choosen type currentTransaction = createTransaction(mainMenuSelection); currentTransaction.execute(); // execute transaction break; case EXIT : // user choose to terminate session screen.displayMessageLine("\nExiting the system..."); userExited = true; // this ATM session should end break; default : // user did not enter an integer between 1-4 screen.displayMessageLine("\nYou did not enter a valid selection."); screen.displayMessageLine("Please try again."); break; } // end switch } // end while } // end method performTransactions // display the main menu and return an input selection private int displayMainMenu(){ screen.displayMessageLine("\nMain Menu :"); screen.displayMessageLine("1 - View my balance"); screen.displayMessageLine("2 - Withdraw cash"); screen.displayMessageLine("3 - Deposit funds"); screen.displayMessageLine("4 - Exit\n"); screen.displayMessage("Enter a choice : "); return keypad.getInput(); // return user's selection } // end method of displayMainMenu // return object of specified Transaction subclass private Transaction createTransaction(int type){ Transaction temp = null; // temporary Transaction variable // determine which type of Transaction to create switch(type){ case BALANCE_INQUIRY : // create new BalanceInquiry transaction temp = new BalanceInquiry(currentAccountNumber, screen, bankDatabase); break; case WITHDRAWAL : // create new Withdrawal transaction temp = new Withdrawal(currentAccountNumber, screen, bankDatabase, keypad, cashDispenser); break; case DEPOSIT : // create new Deposit transaction temp = new Deposit(currentAccountNumber, screen, bankDatabase, keypad, depositSlot); break; } // end switch return temp; // return newly created object } // end method createTransaction } // end class ATM
Source code class Screen:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class Screen { // display a message without a carriage return public void displayMessage(String message){ System.out.print(message); } // end method displayMessage // display a message with a carriage return public void displayMessageLine(String message){ System.out.println(message); } // end method displayMessageLine // displays a dollar amount public void displayDollarAmount(double amount){ System.out.printf("$%,.2f", amount); } // end method displayDollarAmount } // end class Screen
Source code class Keypad:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ import java.util.Scanner; public class Keypad { private Scanner input; // reads data from the command line // no-argument constructor initializes the Scanner public Keypad(){ input = new Scanner(System.in); } // end no-argument Keypad constructor // return an integer value entered by user public int getInput(){ return input.nextInt(); // we assume that user enters an integer } // end method getInput } // end class Keypad
Source code class CashDispenser:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class CashDispenser { // the default initial number of bills in the cash dispenser private final static int INITIAL_COUNT = 500; private int count; // number of $20 bills remaining // no-argument CashDispenser constructor initializes count to default public CashDispenser(){ count = INITIAL_COUNT; // set count attribute to default } // end CashDispenser constructor // simulates dispensing of specified amount of cash public void dispenseCash(int amount){ int billsRequired = amount / 20; // number of $20 bills required count -= billsRequired; // update the count of bills } // end method dispenseCash // indicates whether cash dispenser can dispense desired amount public boolean isSufficientCashAvailable(int amount){ int billsRequired = amount / 20; if(count >= billsRequired){ return true; // enough bills required } else{ return false; // not enough bills required } } // end method isSufficientCashAvailable } // end class CashDispenser
Source code class DepositSlot:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class DepositSlot { // indicate whether envelope was received (always returns true) // because this is only a software simulation of a real deposit slot public boolean isEnvelopeReceived(){ return true; // deposit envelope was received } // end method isEnvelopeReceived } // end class DepositSlot
Source code class Account:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class Account { private int accountNumber; // account number private int pin; // PIN for authentication private double availableBalance; // funds available for withdrawal private double totalBalance; // funds available + pending deposits // Account constructor initializes attributes public Account(int theAccountNumber, int thePIN, double theAvailableBalance, double theTotalBalance){ accountNumber = theAccountNumber; pin = thePIN; availableBalance = theAvailableBalance; totalBalance = theTotalBalance; } // end Account constructor // determines whether a user-specified PIN matches PIN in Account public boolean validatePIN(int userPIN){ if(userPIN == pin){ return true; // means the PIN input is match with the user's PIN } else{ return false; // means the PIN input is not match with the user's PIN } } // end method validatePIN // returns available balance public double getAvailableBalance(){ return availableBalance; } // returns the total balance public double getTotalBalance(){ return totalBalance; } // credits an amount to the account public void credit(double amount){ totalBalance += amount; // add to total balance } // debits an amount from the account public void debit(double amount){ availableBalance -= amount; // substract from available balance totalBalance -= amount; // substract from total balance } // returns account number public int getAccountNumber(){ return accountNumber; } } // end class Account
Source code class BankDatabase:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class BankDatabase { private Account[] accounts; // array of Accounts // no-argument BankDatabase constructor initializes accounts public BankDatabase(){ accounts = new Account[2]; // just 2 accounts for testing accounts[0] = new Account(12345, 54321, 1000.0, 1200.0); accounts[1] = new Account(98765, 56789, 200.0, 200.0); } // end no-argument BankDatabase constructor // retrieve Account object containing specified account number private Account getAccount(int accountNumber){ // loop through accounts searching for matching account number for(Account currentAccount : accounts){ // return current account if match found if(currentAccount.getAccountNumber() == accountNumber) return currentAccount; } // end for return null; // if no matching account was found, return null } // end method // determine whether user-specified account number and PIN match // those of an account in the database public boolean authenticateUser(int userAccountNumber, int userPIN){ // attempt to retrieve the account with the account number Account userAccount = getAccount(userAccountNumber); if(userAccount != null){ return userAccount.validatePIN(userPIN); } else{ return false; // account number not found, so return false } } // end method // return available balance of Account with specified account number public double getAvailableBalance(int userAccountNumber){ return getAccount(userAccountNumber).getAvailableBalance(); } // end method public double getTotalBalance(int userAccountNumber){ return getAccount(userAccountNumber).getTotalBalance(); } // end method public void credit(int userAccountNumber, double amount){ getAccount(userAccountNumber).credit(amount); } // end method public void debit(int userAccountNumber, double amount){ getAccount(userAccountNumber).debit(amount); } // end method } // end class BankDatabase
Source code class Transaction:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public abstract class Transaction { private int accountNumber; // indicates account involved private Screen screen; // ATM's screen private BankDatabase bankDatabase; // account info database // Transaction constructor invoked by subclasses using super() public Transaction(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){ accountNumber = userAccountNumber; screen = atmScreen; bankDatabase = atmBankDatabase; } // end Transaction constructor // return account number public int getAccountNumber(){ return accountNumber; } // end method // return reference to screen public Screen getScreen(){ return screen; } // end method // return reference to bank database public BankDatabase getBankDatabase(){ return bankDatabase; } // end method // perform the transaction (overridden by each subclass) abstract public void execute(); } // end class Transaction
Source code class BalanceInquiry:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class BalanceInquiry extends Transaction { // BalanceInquiry constructor public BalanceInquiry(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){ super(userAccountNumber, atmScreen, atmBankDatabase); } // end BalanceInquiry constructor // performs the transaction @Override public void execute(){ // get references to bank database and screen BankDatabase bankDatabase = getBankDatabase(); Screen screen = getScreen(); // get the available balance for the account involved double availableBalance = bankDatabase.getAvailableBalance(getAccountNumber()); // get the total balance for the account involved double totalBalance = bankDatabase.getTotalBalance(getAccountNumber()); // display the balance information on the screen screen.displayMessageLine("\nBalance Information : "); screen.displayMessage(" - Available Balance : "); screen.displayDollarAmount(availableBalance); screen.displayMessage("\n - Total Balance : "); screen.displayDollarAmount(totalBalance); screen.displayMessageLine(""); } // end method execute } // end class BalanceInquiry
Source code class Withdrawal:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class Withdrawal extends Transaction { private int amount; // amount to withdraw private Keypad keypad; // references to keypad private CashDispenser cashDispenser; // references to cash dispenser // constant corresponding to menu option to cancel private final static int CANCELED = 6; // Withdrawal constructor public Withdrawal(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, CashDispenser atmCashDispenser){ // initializes superclass variables super(userAccountNumber, atmScreen, atmBankDatabase); // initializes references to keypad and cash dispenser keypad = atmKeypad; cashDispenser = atmCashDispenser; } // end Withdrawal constructor // perform transaction @Override public void execute(){ boolean cashDispensed = false; // cash was not dispensed yet double availableBalance; // amount available for withdrawal // get references to bank database and screen BankDatabase bankDatabase = getBankDatabase(); Screen screen = getScreen(); // loop until cash is dispensed or the user cancels do{ // obtain a chosen withdrawal amount from the user amount = displayMenuOfAmounts(); // check whether user choose a withdrawal amount or canceled if(amount != CANCELED){ // get available balance of account involved availableBalance = bankDatabase.getAvailableBalance(getAccountNumber()); // check whether the user has enough money in the account if(amount <= availableBalance){ // check whether the cash dispenser has enough money if(cashDispenser.isSufficientCashAvailable(amount)){ // update the account involved to reflect the withdrawal bankDatabase.debit(getAccountNumber(), amount); cashDispenser.dispenseCash(amount); // dispense cash cashDispensed = true; // cash was dispensed // instructs user to take cash screen.displayMessageLine("\nYour cash has been dispensed. Please take your cash now."); } // end if else{ // cash dispenser does not have enough cash screen.displayMessageLine("\nInsufficient cash available in the ATM."); screen.displayMessageLine("\nPlease choose a smaller amount."); } // end if } // end if else{ // not enough money available in user's account screen.displayMessageLine("\nInsufficient funds in your account."); screen.displayMessageLine("\nPlease choose a smaller amount."); } // end if } // end if else{ // user choose cancel menu option screen.displayMessageLine("\nCancelling transactions..."); return; // return to main menu because user canceled } // end if } while(!cashDispensed); } // end method execute // display a menu of withdrawal amounts and the options to cancel // return the chosen amount or 0 if the user chooses to cancel private int displayMenuOfAmounts(){ int userChoice = 0; // local variable to store return value Screen screen = getScreen(); // get screen references // array of amounts to correspond to menu numbers int[] amounts = {0, 20, 40, 60, 100, 200}; // loop while no valid choice has been made while(userChoice == 0){ // display the withdrawal menu screen.displayMessageLine("\nWithdrawal Menu : "); screen.displayMessageLine("1 - $20"); screen.displayMessageLine("2 - $40"); screen.displayMessageLine("3 - $60"); screen.displayMessageLine("4 - $100"); screen.displayMessageLine("5 - $200"); screen.displayMessageLine("6 - Cancel Transaction"); screen.displayMessage("\nChoose a withdrawal amount : "); int input = keypad.getInput(); // get user input through keypad // determine how to proceed based on the input value switch(input){ // if the user choose a withdrawal amount // i.e choose option 1, 2, 3, 4 or 5 // return the corresponding amount from amounts's array case 1 : case 2 : case 3 : case 4 : case 5 : userChoice = amounts[input]; // save user's choice break; case CANCELED : // the user choose to cancel userChoice = CANCELED; // save user's choice break; default : // the user did not enter value between 1-6 screen.displayMessageLine("\nInvalid selection."); screen.displayMessageLine("Try again."); } // end switch } // end while return userChoice; // return withdrawal amount or CANCELED } // end method displayMenuOfAmounts } // end class Withdrawal
Source code class Deposit:
/** * OOP dalam mesin ATM * * Monica I H * 08 Mei 2017 */ public class Deposit extends Transaction { private double amount; // amount to deposit private Keypad keypad; // references to keypad private DepositSlot depositSlot; // references to deposit slot private final static int CANCELED = 0; // constant for cancel option // Deposit constructor public Deposit(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, DepositSlot atmDepositSlot){ // initializes superclass variables super(userAccountNumber, atmScreen, atmBankDatabase); // initialize references to keypad and deposit slot keypad = atmKeypad; depositSlot = atmDepositSlot; } // end Deposit constructor // perform transaction @Override public void execute(){ BankDatabase bankDatabase = getBankDatabase(); // get reference Screen screen = getScreen(); // get reference amount = promptForDepositAmount(); // get deposit amount from user // check whether the user entered a deposit amount or canceled if(amount != CANCELED){ // request deposit envelope containing specified amount screen.displayMessage("\nPlease insert a deposit envelope containing "); screen.displayDollarAmount(amount); screen.displayMessage("."); // receive deposit envelope boolean envelopeReceived = depositSlot.isEnvelopeReceived(); // check whether deposit envelope was received if(envelopeReceived){ screen.displayMessageLine("\nYour envelope has been received."); screen.displayMessage("NOTE: The money just deposited will not be available until we verify the amount"); screen.displayMessage("of any enclosed cash and your checks clear."); // credit account to reflect the deposit bankDatabase.credit(getAccountNumber(), amount); } // end if else{ // deposit envelope not received screen.displayMessageLine("\nYou did not insert an envelope"); screen.displayMessageLine("So, the ATM has canceled your transaction."); } // end else } // end if else{ // user canceled instead of entering amount screen.displayMessageLine("\nCanceling transaction..."); } // end else } // end method execute // prompt user to enter a deposit amount in cents private double promptForDepositAmount(){ Screen screen = getScreen(); // get references to screen // display the prompt screen.displayMessage("\nPlease enter a deposit amount in CENTS (or 0 to cancel)"); int input = keypad.getInput(); // receive input of deposit amount // check whether the user canceled or entered a valid amount if(input == CANCELED) return CANCELED; else{ return (double) input / 100; // return dollar amount } // end else } // end method } // end class Deposit