Minggu, 14 Mei 2017

OOP dalam mesin ATM

Pada kali ini, saya akan mencoba membuat program mesin ATM.

Untuk source code aslinya bisa di lihat pada buku "Java - How to Program, 9th edition by Deitel".

Source code : ATM

  1. public class ATM  
  2.  {  
  3.    private boolean userAuthenticated;  
  4.    private int currentAccountNumber;  
  5.    private Screen screen;  
  6.    private Keypad keypad;  
  7.    private CashDispenser cashDispenser;  
  8.    private DepositSlot depositSlot;  
  9.    private BankDatabase bankDatabase;  
  10.      
  11.    private static final int BALANCE_INQUIRY = 1;  
  12.    private static final int WITHDRAWAL = 2;  
  13.    private static final int DEPOSIT = 3;  
  14.    private static final int EXIT = 4;  
  15.      
  16.    public ATM()  
  17.    {  
  18.      userAuthenticated = false;  
  19.      currentAccountNumber = 0;  
  20.      screen = new Screen();  
  21.      keypad = new Keypad();  
  22.      cashDispenser = new CashDispenser();  
  23.      depositSlot = new DepositSlot();  
  24.      bankDatabase = new BankDatabase();  
  25.    }  
  26.      
  27.    public void run()  
  28.    {  
  29.      while(true)  
  30.      {  
  31.        while(!userAuthenticated)  
  32.        {  
  33.          screen.displayMessageLine("\nSelamat Datang!");  
  34.          authenticateUser();  
  35.        }  
  36.          
  37.        performTransactions();  
  38.        userAuthenticated = false;  
  39.        currentAccountNumber = 0;  
  40.        screen.displayMessageLine("\nTerima Kasih! Jaga kerahasiaan password anda!");  
  41.      }  
  42.    }  
  43.      
  44.    private void authenticateUser()  
  45.    {  
  46.      screen.displayMessage("\nSilahkan masukkan ID AKUN anda: ");  
  47.      int accountNumber = keypad.getInput();  
  48.      screen.displayMessage("\nSilahkan masukkan PIN anda: ");  
  49.      int pin = keypad.getInput();  
  50.        
  51.      userAuthenticated = bankDatabase.authenticateUser(accountNumber, pin);  
  52.        
  53.      if(userAuthenticated)  
  54.      {  
  55.        currentAccountNumber = accountNumber;  
  56.      }  
  57.      else  
  58.        screen.displayMessageLine("PIN atau ID AKUN salah. Silahkan masukkan kembali.");  
  59.    }  
  60.      
  61.    private void performTransactions()  
  62.    {  
  63.      Transaction currentTransaction = null;  
  64.      boolean userExited = false;  
  65.        
  66.      while(!userExited)  
  67.      {  
  68.        int mainMenuSelection = displayMainMenu();  
  69.          
  70.        switch(mainMenuSelection)  
  71.        {  
  72.          case BALANCE_INQUIRY:  
  73.          case WITHDRAWAL:  
  74.          case DEPOSIT:  
  75.            currentTransaction = createTransaction(mainMenuSelection);  
  76.            currentTransaction.execute();  
  77.            break;  
  78.          case EXIT:  
  79.            screen.displayMessageLine("\nSilahkan ambil kartu atm anda.");  
  80.            userExited = true;  
  81.            break;  
  82.          default:  
  83.            screen.displayMessageLine("\nPilihan tidak tersedia. Silahkan masukkan pilihan anda.");  
  84.            break;  
  85.        }  
  86.      }  
  87.    }  
  88.      
  89.    private int displayMainMenu()  
  90.    {  
  91.      screen.displayMessageLine("\nMain menu:");  
  92.      screen.displayMessageLine("1. Cek Saldo");  
  93.      screen.displayMessageLine("2. Tarik Tunai");  
  94.      screen.displayMessageLine("3. Setor Tunai");  
  95.      screen.displayMessageLine("4. Keluar\n");  
  96.      screen.displayMessage("Masukkan Pilihan anda:");  
  97.      return keypad.getInput();  
  98.    }  
  99.      
  100.    private Transaction createTransaction(int type)  
  101.    {  
  102.      Transaction temp = null;  
  103.        
  104.      switch(type)  
  105.      {  
  106.        case BALANCE_INQUIRY:  
  107.          temp = new BalanceInquiry(currentAccountNumber, screen, bankDatabase);  
  108.          break;  
  109.        case WITHDRAWAL:  
  110.          temp = new Withdrawal(currentAccountNumber, screen, bankDatabase, keypad, cashDispenser);  
  111.          break;  
  112.        case DEPOSIT:  
  113.          temp = new Deposit(currentAccountNumber, screen, bankDatabase, keypad, depositSlot);  
  114.          break;  
  115.      }  
  116.      return temp;  
  117.    }  
  118.  }

Source code : DepositSlot

  1.  public class DepositSlot  
  2.  {  
  3.    public boolean isEnvelopeReceived()  
  4.    {  
  5.      return true;  
  6.    }  
  7.  }

Source code : Screen

  1.  public class Screen  
  2.  {  
  3.    public void displayMessage(String message)  
  4.    {  
  5.      System.out.print(message);  
  6.    }  
  7.      
  8.    public void displayMessageLine(String message)  
  9.    {  
  10.      System.out.println(message);  
  11.    }  
  12.      
  13.    public void displayDollarAmount(double amount)  
  14.    {  
  15.      System.out.printf("Rp.%,.2f", amount);  
  16.    }  
  17.  }

Source code : Keypad

  1.  import java.util.Scanner;  
  2.    
  3.  public class Keypad  
  4.  {  
  5.    private Scanner input;  
  6.      
  7.    public Keypad()  
  8.    {  
  9.      input = new Scanner(System.in);  
  10.    }  
  11.      
  12.    public int getInput()  
  13.    {  
  14.      return input.nextInt();  
  15.    }  
  16.  }

Source code : CashDispenser

  1.  public class CashDispenser  
  2.  {  
  3.    private final static int INITIAL_COUNT = 50000;  
  4.    private int count;  
  5.      
  6.    public CashDispenser()  
  7.    {  
  8.      count = INITIAL_COUNT;  
  9.    }  
  10.      
  11.    public void dispenseCash(int amount)  
  12.    {  
  13.      int billsRequired = amount / 20;  
  14.      count -= billsRequired;  
  15.    }  
  16.      
  17.    public boolean isSufficientCashAvailable(int amount)  
  18.    {  
  19.      int billsRequired = amount / 20;  
  20.        
  21.      if(count >= billsRequired)  
  22.        return true;  
  23.      else  
  24.        return false;  
  25.    }  
  26.  }

Source code : Transaction

  1.  public abstract class Transaction  
  2.  {  
  3.    private int accountNumber;  
  4.    private Screen screen;  
  5.    private BankDatabase bankDatabase;  
  6.      
  7.    public Transaction(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase)  
  8.    {  
  9.      accountNumber = userAccountNumber;  
  10.      screen = atmScreen;  
  11.      bankDatabase = atmBankDatabase;  
  12.    }  
  13.      
  14.    public int getAccountNumber()  
  15.    {  
  16.      return accountNumber;  
  17.    }  
  18.      
  19.    public Screen getScreen()  
  20.    {  
  21.      return screen;  
  22.    }  
  23.      
  24.    public BankDatabase getBankDatabase()  
  25.    {  
  26.      return bankDatabase;  
  27.    }  
  28.      
  29.    abstract public void execute();  
  30.  }

Source code : Withdrawal

  1.  public class Withdrawal extends Transaction  
  2.  {  
  3.    private int amount;  
  4.    private Keypad keypad;  
  5.    private CashDispenser cashDispenser;  
  6.      
  7.    private final static int CANCELED = 6;  
  8.      
  9.    public Withdrawal(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase,  
  10.      Keypad atmKeypad, CashDispenser atmCashDispenser)  
  11.    {  
  12.      super(userAccountNumber, atmScreen, atmBankDatabase);  
  13.        
  14.      keypad = atmKeypad;  
  15.      cashDispenser = atmCashDispenser;  
  16.    }  
  17.      
  18.    @Override  
  19.    public void execute()  
  20.    {  
  21.      boolean cashDispensed = false;  
  22.      double availableBalance;  
  23.        
  24.      BankDatabase bankDatabase = getBankDatabase();  
  25.      Screen screen = getScreen();  
  26.        
  27.      do  
  28.      {  
  29.        amount = displayMenuOfAmounts();  
  30.          
  31.        if(amount != CANCELED)  
  32.        {  
  33.          availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());  
  34.            
  35.          if(amount <= availableBalance)  
  36.          {  
  37.            if(cashDispenser.isSufficientCashAvailable(amount))  
  38.            {  
  39.              bankDatabase.debit(getAccountNumber(), amount);  
  40.                
  41.              cashDispenser.dispenseCash(amount);  
  42.              cashDispensed = true;  
  43.                
  44.              screen.displayMessageLine("\nSaldo anda telah " + " dipotong. Silahkan ambil uang anda sekarang.");  
  45.            }  
  46.            else  
  47.              screen.displayMessageLine("\nSaldo tidak cukup." +  
  48.                "\n\nSilahkan pilih jumlah yang lebih kecil.");  
  49.          }  
  50.          else  
  51.          {  
  52.            screen.displayMessageLine("\nSaldo tidak cukup." +  
  53.              "\n\nSilahkan pilih jumlah yang lebih kecil.");  
  54.          }  
  55.        }  
  56.        else  
  57.        {  
  58.          screen.displayMessageLine("\nMembatalkan transaksi...");  
  59.          return;  
  60.        }  
  61.      } while(!cashDispensed);  
  62.    }  
  63.      
  64.    private int displayMenuOfAmounts()  
  65.    {  
  66.      int userChoice = 0;  
  67.        
  68.      Screen screen = getScreen();  
  69.        
  70.      int[] amounts = {0, 50000, 100000, 200000, 300000, 500000};  
  71.        
  72.      while(userChoice == 0)  
  73.      {  
  74.        screen.displayMessageLine("\nPilihan tarik tunai:");  
  75.        screen.displayMessageLine("1. Rp. 50.000");  
  76.        screen.displayMessageLine("2. Rp. 100.000");  
  77.        screen.displayMessageLine("3. Rp. 200.000");  
  78.        screen.displayMessageLine("4. Rp. 300.000");  
  79.        screen.displayMessageLine("5. Rp. 500.000");  
  80.        screen.displayMessageLine("0. Batalkan");  
  81.        screen.displayMessageLine("\nSilahkan masukkan pilihan anda:");  
  82.          
  83.        int input = keypad.getInput();  
  84.          
  85.        switch(input)  
  86.        {  
  87.          case 1:  
  88.          case 2:  
  89.          case 3:  
  90.          case 4:  
  91.          case 5:  
  92.            userChoice = amounts[input];  
  93.            break;  
  94.          case 0:  
  95.            userChoice = CANCELED;  
  96.            break;  
  97.          default:  
  98.            screen.displayMessageLine("\nPilihan tidak tersedia. Silahkan masukkan pilihan anda.");  
  99.        }  
  100.      }  
  101.        
  102.      return userChoice;  
  103.    }  
  104.  }

Source code : Deposit

  1. public class Deposit extends Transaction  
  2.  {  
  3.    private double amount;  
  4.    private Keypad keypad;  
  5.    private DepositSlot depositSlot;  
  6.    private final static int CANCELED = 0;  
  7.      
  8.    public Deposit(int userAccountNumber, Screen atmScreen,  
  9.      BankDatabase atmBankDatabase, Keypad atmKeypad,  
  10.      DepositSlot atmDepositSlot)  
  11.    {  
  12.      super(userAccountNumber, atmScreen, atmBankDatabase);  
  13.        
  14.      keypad = atmKeypad;  
  15.      depositSlot = atmDepositSlot;  
  16.    }  
  17.    
  18.    @Override  
  19.    public void execute()  
  20.    {  
  21.      BankDatabase bankDatabase = getBankDatabase();  
  22.      Screen screen = getScreen();  
  23.        
  24.      amount = promptForDepositAmount();  
  25.        
  26.      if(amount != CANCELED)  
  27.      {  
  28.        screen.displayMessage("\nSilahkan masukkan uang anda");  
  29.        screen.displayDollarAmount(amount);  
  30.        screen.displayMessageLine(".");  
  31.          
  32.        boolean envelopeReceived = depositSlot.isEnvelopeReceived();  
  33.          
  34.        if(envelopeReceived)  
  35.        {  
  36.          screen.displayMessageLine("\nUang anda telah" +  
  37.            "diterima.\nKETERANGAN : Uang belum dapat diambil " +  
  38.            "sampai setelah kita melakukan verifikasi.");  
  39.          bankDatabase.credit(getAccountNumber(), amount);  
  40.        }  
  41.        else  
  42.        {  
  43.          screen.displayMessageLine("\nAnda belum memasukkan " +  
  44.            "uang anda, ATM sedang membatalkan transaksi anda.");  
  45.        }  
  46.      }  
  47.      else  
  48.      {  
  49.        screen.displayMessageLine("\nMembatalkan transaksi...");  
  50.      }  
  51.    }  
  52.      
  53.    private double promptForDepositAmount()  
  54.    {  
  55.      Screen screen = getScreen();  
  56.        
  57.      screen.displayMessage("\nSilahkan masukkan jumlah uang dalam " + "RUPIAH (Tekan 0 untuk membatalkan): ");  
  58.      int input = keypad.getInput();  
  59.        
  60.      if(input == CANCELED)  
  61.        return CANCELED;  
  62.      else  
  63.      {  
  64.        return(double) input / 1;  
  65.      }  
  66.    }  
  67.  }

Source code : BalanceInquiry

  1. public class BalanceInquiry extends Transaction  
  2.  {  
  3.    public BalanceInquiry(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase)  
  4.    {  
  5.      super(userAccountNumber, atmScreen, atmBankDatabase);  
  6.    }  
  7.      
  8.    @Override  
  9.    public void execute()  
  10.    {  
  11.      BankDatabase bankDatabase = getBankDatabase();  
  12.      Screen screen = getScreen();  
  13.        
  14.      double availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());  
  15.        
  16.      double totalBalance = bankDatabase.getTotalBalance(getAccountNumber());  
  17.        
  18.      screen.displayMessageLine("\nSaldo anda:");  
  19.      screen.displayMessage(" - Saldo tersedia:");  
  20.      screen.displayDollarAmount(availableBalance);  
  21.      screen.displayMessage("\n - Saldo total:   ");  
  22.      screen.displayDollarAmount(totalBalance);  
  23.      screen.displayMessageLine("");  
  24.    }  
  25.  }

Source code : BankDatabase

  1. public class BankDatabase  
  2.  {  
  3.    private Account[] accounts;  
  4.      
  5.    public BankDatabase()  
  6.    {  
  7.      accounts = new Account[2];  
  8.      accounts[0] = new Account(12345, 54321, 1000000, 1200000);  
  9.      accounts[1] = new Account(98765, 56789, 2000000, 2000000);  
  10.    }  
  11.      
  12.    private Account getAccount(int accountNumber)  
  13.    {  
  14.      for(Account currentAccount : accounts)  
  15.      {  
  16.        if(currentAccount.getAccountNumber() == accountNumber)  
  17.          return currentAccount;  
  18.      }  
  19.        
  20.      return null;  
  21.    }  
  22.      
  23.    public boolean authenticateUser(int userAccountNumber, int userPIN)  
  24.    {  
  25.      Account userAccount = getAccount(userAccountNumber);  
  26.        
  27.      if(userAccount != null)  
  28.        return userAccount.validatePIN(userPIN);  
  29.      else  
  30.        return false;  
  31.    }  
  32.      
  33.    public double getAvailableBalance(int userAccountNumber)  
  34.    {  
  35.      return getAccount(userAccountNumber).getAvailableBalance();  
  36.    }  
  37.      
  38.    public double getTotalBalance(int userAccountNumber)  
  39.    {  
  40.      return getAccount(userAccountNumber).getTotalBalance();  
  41.    }  
  42.      
  43.    public void credit( int userAccountNumber, double amount)  
  44.    {  
  45.      getAccount(userAccountNumber).credit(amount);  
  46.    }  
  47.      
  48.    public void debit(int userAccountNumber, double amount)  
  49.    {  
  50.      getAccount(userAccountNumber).debit(amount);  
  51.    }  
  52.  }

Source code : Account

  1.  public class Account  
  2.  {  
  3.    private int accountNumber;  
  4.    private int pin;  
  5.    private double availableBalance;  
  6.    private double totalBalance;  
  7.      
  8.    public Account(int theAccountNumber, int thePIN, double theAvailableBalance, double theTotalBalance)  
  9.    {  
  10.      accountNumber = theAccountNumber;  
  11.      pin = thePIN;  
  12.      availableBalance = theAvailableBalance;  
  13.      totalBalance = theTotalBalance;  
  14.    }  
  15.      
  16.    public boolean validatePIN(int userPIN)  
  17.    {  
  18.      if(userPIN == pin)  
  19.        return true;  
  20.      else  
  21.        return false;  
  22.    }  
  23.      
  24.    public double getAvailableBalance()  
  25.    {  
  26.      return availableBalance;  
  27.    }  
  28.      
  29.    public double getTotalBalance()  
  30.    {  
  31.      return totalBalance;  
  32.    }  
  33.      
  34.    public void credit(double amount)  
  35.    {  
  36.      totalBalance += amount;  
  37.    }  
  38.      
  39.    public void debit(double amount)  
  40.    {  
  41.      availableBalance -= amount;  
  42.      totalBalance -= amount;  
  43.    }  
  44.      
  45.    public int getAccountNumber()  
  46.    {  
  47.      return accountNumber;  
  48.    }  
  49.  }

Source code : ATMCaseStudy

  1.  public class ATMCaseStudy  
  2.  {  
  3.    //main method creates and runs the ATM  
  4.    public static void main(String[] args)  
  5.    {  
  6.      ATM theATM = new ATM();  
  7.      theATM.run();  
  8.    }  
  9.  }

Hasilnya:

1. Cek saldo



2. Tarik tunai



3. Setor tunai



4. Keluar