23.4.10. Class Withdrawal

Class Withdrawal (Figs. 23.3223.33) derives from Transaction and represents a withdrawal ATM transaction. Figure 23.32 expands upon the header file for this class developed in Fig. 23.13. Class Withdrawal has a constructor and one member function execute, which we discuss shortly. Recall from the class diagram of Fig. 23.11 that class Withdrawal has one attribute, amount, which line 16 implements as an int data member. Figure 23.10 models associations between class Withdrawal and classes Keypad and CashDispenser, for which lines 17–18 implement references keypad and cashDispenser, respectively. Line 19 is the function prototype of a private utility function that we soon discuss.


 1   // Withdrawal.h
 2   // Withdrawal class definition. Represents a withdrawal transaction.
 3   #ifndef WITHDRAWAL_H
 4   #define WITHDRAWAL_H
 5
 6   #include "Transaction.h" // Transaction class definition
 7   class Keypad; // forward declaration of class Keypad
 8   class CashDispenser; // forward declaration of class CashDispenser
 9
10   class Withdrawal : public Transaction
11   {
12   public:
13      Withdrawal( int, Screen &, BankDatabase &, Keypad &, CashDispenser & );
14      virtual void execute(); // perform the transaction
15   private:
16      int amount; // amount to withdraw
17      Keypad &keypad; // reference to ATM's keypad
18      CashDispenser &cashDispenser; // reference to ATM's cash dispenser
19      int displayMenuOfAmounts() const; // display the withdrawal menu
20   }; // end class Withdrawal
21
22   #endif // WITHDRAWAL_H


Fig. 23.32. Withdrawal class definition.


 1   // Withdrawal.cpp
 2   // Member-function definitions for class Withdrawal.
 3   #include "Withdrawal.h" // Withdrawal class definition
 4   #include "Screen.h" // Screen class definition
 5   #include "BankDatabase.h" // BankDatabase class definition
 6   #include "Keypad.h" // Keypad class definition
 7   #include "CashDispenser.h" // CashDispenser class definition
 8
 9   // global constant that corresponds to menu option to cancel
10   static const int CANCELED = 6;
11
12   // Withdrawal constructor initialize class's data members
13   Withdrawal::Withdrawal( int userAccountNumber, Screen &atmScreen,
14      BankDatabase &atmBankDatabase, Keypad &atmKeypad,
15      CashDispenser &atmCashDispenser )
16      : Transaction( userAccountNumber, atmScreen, atmBankDatabase ),
17        keypad( atmKeypad ), cashDispenser( atmCashDispenser )
18   {
19      // empty body
20   } // end Withdrawal constructor
21
22   // perform transaction; overrides Transaction's pure virtual function
23   void Withdrawal::execute()
24   {
25      bool cashDispensed = false; // cash was not dispensed yet
26      bool transactionCanceled = false; // transaction was not canceled yet
27
28      // get references to bank database and screen
29      BankDatabase &bankDatabase = getBankDatabase();
30      Screen &screen = getScreen();
31
32      // loop until cash is dispensed or the user cancels
33      do
34      {
35         // obtain the chosen withdrawal amount from the user
36         int selection = displayMenuOfAmounts();
37
38         // check whether user chose a withdrawal amount or canceled
39         if ( selection != CANCELED )
40         {
41            amount = selection; // set amount to the selected dollar amount
42
43            // get available balance of account involved
44            double availableBalance =
45               bankDatabase.getAvailableBalance( getAccountNumber() );
46
47            // check whether the user has enough money in the account
48            if ( amount <= availableBalance )
49            {
50               // check whether the cash dispenser has enough money
51               if ( cashDispenser.isSufficientCashAvailable( amount ) )
52               {
53                  // update the account involved to reflect withdrawal
54                  bankDatabase.debit( getAccountNumber(), amount );
55
56                  cashDispenser.dispenseCash( amount ); // dispense cash
57                  cashDispensed = true; // cash was dispensed
58
59                  // instruct user to take cash
60                  screen.displayMessageLine(
61                     " Please take your cash from the cash dispenser." );
62               } // end if
63               else // cash dispenser does not have enough cash
64                  screen.displayMessageLine(
65                     " Insufficient cash available in the ATM."
66                     " Please choose a smaller amount." );
67            } // end if
68            else // not enough money available in user's account
69            {
70               screen.displayMessageLine(
71                  " Insufficient funds in your account."
72                  " Please choose a smaller amount." );
73            } // end else
74         } // end if
75         else // user chose cancel menu option
76         {
77            screen.displayMessageLine( " Canceling transaction..." );
78            transactionCanceled = true; // user canceled the transaction
79         } // end else
80      } while ( !cashDispensed && !transactionCanceled ); // end do...while
81   } // end function execute
82
83   // display a menu of withdrawal amounts and the option to cancel;
84   // return the chosen amount or 0 if the user chooses to cancel
85   int Withdrawal::displayMenuOfAmounts() const
86   {
87      int userChoice = 0; // local variable to store return value
88
89      Screen &screen = getScreen(); // get screen reference
90
91      // array of amounts to correspond to menu numbers
92      int amounts[] = { 0, 20, 40, 60, 100, 200 };
93
94      // loop while no valid choice has been made
95      while ( userChoice == 0 )
96      {
97         // display the menu
98         screen.displayMessageLine( " Withdrawal options:" );
99         screen.displayMessageLine( "1 - $20" );
100        screen.displayMessageLine( "2 - $40" );
101        screen.displayMessageLine( "3 - $60" );
102        screen.displayMessageLine( "4 - $100" );
103        screen.displayMessageLine( "5 - $200" );
104        screen.displayMessageLine( "6 - Cancel transaction" );
105        screen.displayMessage( " Choose a withdrawal option (1-6): " );
106
107        int input = keypad.getInput(); // get user input through keypad
108
109        // determine how to proceed based on the input value
110        switch ( input )
111        {
112           case 1: // if the user chose a withdrawal amount
113           case 2: // (i.e., chose option 1, 2, 3, 4 or 5), return the
114           case 3: // corresponding amount from amounts array
115           case 4:
116           case 5:
117              userChoice = amounts[ input ]; // save user's choice
118              break;
119           case CANCELED: // the user chose to cancel
120              userChoice = CANCELED; // save user's choice
121              break;
122           default: // the user did not enter a value from 1-6
123              screen.displayMessageLine(
124                 " Ivalid selection. Try again." );
125        } // end switch
126     } // end while
127
128     return userChoice; // return withdrawal amount or CANCELED
129  } // end function displayMenuOfAmounts


Fig. 23.33. Withdrawal class member-function definitions.

Withdrawal Class Member-Function Definitions

Figure 23.33 contains the member-function definitions for class Withdrawal. Line 3 #includes the class’s definition, and lines 4–7 #include the definitions of the other classes used in Withdrawal’s member functions. Line 11 declares a global constant corresponding to the cancel option on the withdrawal menu. We’ll soon discuss how the class uses this constant.

Class Withdrawal’s constructor (defined in lines 13–20 of Fig. 23.33) has five parameters. It uses a base-class initializer in line 16 to pass parameters userAccountNumber, atmScreen and atmBankDatabase to base class Transaction’s constructor to set the data members that Withdrawal inherits from Transaction. The constructor also takes references atmKeypad and atmCashDispenser as parameters and assigns them to reference data members keypad and cashDispenser using member initializers (line 17).

Class Withdrawal overrides Transaction’s pure virtual function execute with a concrete implementation (lines 23–81) that performs the steps involved in a withdrawal. Line 25 declares and initializes a local bool variable cashDispensed. This variable indicates whether cash has been dispensed (i.e., whether the transaction has completed successfully) and is initially false. Line 26 declares and initializes to false a bool variable transactionCanceled that indicates whether the transaction has been canceled by the user. Lines 29–30 get references to the bank database and the ATM’s screen by invoking member functions inherited from base class Transaction.

Lines 33–80 contain a do...while statement that executes its body until cash is dispensed (i.e., until cashDispensed becomes true) or until the user chooses to cancel (i.e., until transactionCanceled becomes true). This loop continuously returns the user to the start of the transaction if an error occurs (i.e., the requested withdrawal amount is greater than the user’s available balance or greater than the amount of cash in the cash dispenser). Line 36 displays a menu of withdrawal amounts and obtains a user selection by calling private utility function displayMenuOfAmounts (defined in lines 85–129). This function displays the menu of amounts and returns either an int withdrawal amount or the int constant CANCELED to indicate that the user has chosen to cancel the transaction.

Member function displayMenuOfAmounts (lines 85–129) first declares local variable userChoice (initially 0) to store the value that the member function will return (line 87). Line 89 gets a reference to the screen by calling member function getScreen inherited from base class Transaction. Line 92 declares an integer array of withdrawal amounts that correspond to the amounts displayed in the withdrawal menu. We ignore the first element in the array (index 0) because the menu has no option 0. The while statement in lines 95–126 repeats until userChoice takes on a value other than 0. We’ll see shortly that this occurs when the user makes a valid selection from the menu. Lines 98–105 display the withdrawal menu on the screen and prompt the user to enter a choice. Line 107 obtains integer input through the keypad. The switch statement in lines 110–125 determines how to proceed based on the user’s input. If the user selects a number between 1 and 5, line 117 sets userChoice to the value of the element in amounts at index input. For example, if the user enters 3 to withdraw $60, line 117 sets userChoice to the value of amounts[ 3 ] (i.e., 60). Line 118 terminates the switch. Variable userChoice no longer equals 0, so the while in lines 95–126 terminates and line 128 returns userChoice. If the user selects the cancel menu option, lines 120–121 execute, setting userChoice to CANCELED and causing the member function to return this value. If the user does not enter a valid menu selection, lines 123–124 display an error message and the user is returned to the withdrawal menu.

The if statement in line 39 in member function execute determines whether the user has selected a withdrawal amount or chosen to cancel. If the user cancels, lines 77–78 execute to display an appropriate message to the user and set transactionCanceled to true. This causes the loop-continuation test in line 80 to fail and control to return to the calling member function (i.e., ATM member function performTransactions). If the user has chosen a withdrawal amount, line 41 assigns local variable selection to data member amount. Lines 44–45 retrieve the available balance of the current user’s Account and store it in a local double variable availableBalance. Next, the if statement in line 48 determines whether the selected amount is less than or equal to the user’s available balance. If it isn’t, lines 70–72 display an appropriate error message. Control then continues to the end of the do...while, and the loop repeats because both cashDispensed and transactionCanceled are still false. If the user’s balance is high enough, the if statement in line 51 determines whether the cash dispenser has enough money to satisfy the withdrawal request by invoking the cashDispenser’s isSufficientCashAvailable member function. If this member function returns false, lines 64–66 display an appropriate error message and the do...while repeats. If sufficient cash is available, then the requirements for the withdrawal are satisfied, and line 54 debits amount from the user’s account in the database. Lines 56–57 then instruct the cash dispenser to dispense the cash to the user and set cashDispensed to true. Finally, lines 60–61 display a message to the user that cash has been dispensed. Because cashDispensed is now true, control continues after the do...while. No additional statements appear below the loop, so the member function returns control to class ATM.

In the function calls in lines 64–66 and lines 70–72, we divide the argument to Screen member function displayMessageLine into two string literals, each placed on a separate line in the program. We do so because each argument is too long to fit on a single line. C++ concatenates (i.e., combines) string literals adjacent to each other, even if they are on separate lines. For example, if you write "Happy" "Birthday" in a program, C++ will view these two adjacent string literals as the single string literal "Happy Birthday". As a result, when lines 64–66 execute, displayMessageLine receives a single string as a parameter, even though the argument in the function call appears as two string literals.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.138.33