J.2. Class ATMClass ATM (Fig. J.1) represents the ATM as a whole. Lines 410 implement the class's attributes. We determine all but one of these attributes from the UML class diagrams of Fig. 11.19 and Fig. 11.20. Line 4 declares the Boolean attribute userAuthenticated from Fig. 11.21. Line 5 declares an attribute not found in our UML designan Integer attribute currentAccountNumber that keeps track of the account number of the current authenticated user. We will soon see how the class uses this attribute. Lines 610 declare reference-type attributes corresponding to the ATM class's associations modeled in the class diagram of Fig. 11.19. These attributes allow the ATM to access its parts (i.e., its Screen, Keypad, CashDispenser and DepositSlot) and interact with the bank's account information database (i.e., a BankDatabase object). Figure J.1. Class ATM represents the ATM.
Lines 1318 declare an enumeration that corresponds to the four options in the ATM's main menu (i.e., balance inquiry, withdrawal, deposit and exit). Lines 2129 declare class ATM's constructor, which initializes the class's attributes. When an ATM object is first created, no user is authenticated, so line 22 initializes userAuthenticated to False. Line 23 initializes currentAccountNumber to 0 because there is no current user yet. Lines 2427 instantiate new objects to represent the parts of the ATM. Recall that class ATM has composition relationships with classes Screen, Keypad, CashDispenser and DepositSlot, so class ATM is responsible for their creation. Line 28 creates a new BankDatabase. As you will soon see, the BankDatabase creates two Account objects that can be used to test the ATM. [Note: If this were a real ATM system, the ATM class would receive a reference to an existing database object created by the bank. However, in this implementation we are only simulating the bank's database, so class ATM creates the BankDatabase object with which it interacts.] Implementing the OperationThe class diagram of Fig. 11.20 does not list any operations for class ATM. We now implement one operation (i.e., Public method) in class ATM that allows an external client of the class (i.e., module ATMCaseStudy; Section J.13) to tell the ATM to run. ATM method Run (lines 3246) uses an infinite loop (lines 3445) to repeatedly welcome a user, attempt to authenticate the user and, if authentication succeeds, allow the user to perform transactions. After an authenticated user performs the desired transactions and chooses to exit, the ATM resets itself, displays a goodbye message to the user and restarts the process. We use an infinite loop here to simulate the fact that an ATM appears to run continuously until the bank turns it off (an action beyond the user's control). An ATM user has the option to exit the system, but does not have the ability to turn off the ATM completely. Inside method Run's infinite loop, lines 3639 cause the ATM to repeatedly welcome and attempt to authenticate the user as long as the user has not been authenticated (i.e., the condition Not userAuthenticated is TRue). Line 37 invokes method DisplayMessageLine of the ATM's screen to display a welcome message. Like Screen method DisplayMessage designed in the case study, method DisplayMessageLine (declared in lines 1012 of Fig. J.2) displays a message to the user, but this method also outputs a newline after displaying the message. We add this method during implementation to give class Screen's clients more control over the placement of displayed messages. Line 38 invokes class ATM's Private utility method AuthenticateUser (declared in lines 4967) to attempt to authenticate the user. Figure J.2. Class Screen represents the screen of the ATM.
Authenticating the UserWe refer to the requirements document to determine the steps necessary to authenticate the user before allowing transactions to occur. Lines 5051 of method AuthenticateUser invoke method DisplayMessage of the ATM's screen to prompt the user to enter an account number. Line 52 invokes method GetInput of the ATM's keypad to obtain the user's input, then stores the integer value entered by the user in local variable accountNumber. Method AuthenticateUser next prompts the user to enter a PIN (line 53), and stores the PIN input by the user in local variable pin (line 54). Next, lines 5758 attempt to authenticate the user by passing the accountNumber and pin entered by the user to the bank database's AuthenticateUser method. Class ATM sets its userAuthenticated attribute to the Boolean value returned by this methoduserAuthenticated becomes true if authentication succeeds (i.e., accountNumber and pin match those of an existing Account in the bank database) and remains False otherwise. If userAuthenticated is true, line 62 saves the account number entered by the user (i.e., accountNumber) in the ATM attribute currentAccountNumber. The other methods of class ATM use this variable whenever an ATM session requires access to the user's account number. If userAuthenticated is False, lines 6465 use the screenHandle's DisplayMessageLine method to indicate that an invalid account number and/or PIN was entered, so the user must try again. Note that we set currentAccountNumber only after authenticating the user's account number and the associated PINif the database could not authenticate the user, currentAccountNumber remains 0. After method Run attempts to authenticate the user (line 38), if userAuthenticated is still False (line 36), the While loop body (lines 3738) executes again. If userAuthenticated is now TRue, the loop terminates and control continues with line 41, which calls class ATM's Private utility method PerformTransactions. Performing TransactionsMethod PerformTransactions (lines 7096) carries out an ATM session for an authenticated user. Line 71 declares local variable TRansaction to which we assign a BalanceInquiry, Withdrawal or Deposit object representing the ATM transaction currently being processed. Note that we use a transaction variable here to allow us to take advantage of polymorphism. Also note that we name this variable after the role name included in the class diagram of Fig. 4.19currentTransaction. Line 72 declares another local variablea Boolean called userExited that keeps track of whether the user has chosen to exit. This variable controls a While loop (lines 7595) that allows the user to execute an unlimited number of transactions before choosing to exit. Within this loop, line 77 displays the main menu and obtains the user's menu selection by calling ATM utility method DisplayMainMenu (declared in lines 99107). This method displays the main menu by invoking methods of the ATM's screen and returns a menu selection obtained from the user through the ATM's keypad. Line 77 stores the user's selection returned by DisplayMainMenu in local variable mainMenuSelection. After obtaining a main menu selection, method PerformTransactions uses a Select Case statement (lines 8094) to respond to the selection appropriately. If mainMenuSelection is equal to any of the three integer constants representing transaction types (i.e., if the user chose to perform a transaction), line 85 calls utility method CreateTransaction (declared in lines 110129) to return a newly instantiated object of the type that corresponds to the selected transaction. Variable currentTransaction is assigned the reference returned by method CreateTransaction, then line 86 invokes method Execute of this transaction to execute it. We will discuss transaction method Execute and the three transaction derived classes shortly. Note that we assign to the TRansaction variable currentTransaction an object of one of the three transaction derived classes so that we can execute transactions polymorphically. For example, if the user chooses to perform a balance inquiry, mainMenuSelection equals MenuOption.BALANCE_INQUIRY, and CreateTransaction returns a BalanceInquiry object (line 85). Thus, currentTransaction refers to a BalanceInquiry and invoking currentTransaction.Execute() (line 86) results in BalanceInquiry's version of Execute being called. Creating TransactionsMethod CreateTransaction (lines 110129) uses a Select Case statement (lines 115126) to instantiate a new transaction derived class object of the type indicated by the parameter type. Recall that method PerformTransactions passes mainMenuSelection to method CreateTransaction only when mainMenuSelection contains a value corresponding to one of the three transaction types. So parameter type (line 110) receives one of the values MenuOption.BALANCE_INQUIRY, MenuOption.WITHDRAWAL or MenuOption.DEPOSIT. Each Case in the Select Case statement instantiates a new object by calling the appropriate transaction derived class constructor. Note that each constructor has a unique parameter list, based on the specific data required to initialize the derived class object. A BalanceInquiry (lines 118119) requires only the account number of the current user and the ATM's screenHandle and bankDatabaseHandle. In addition to these parameters, a Withdrawal (lines 121122) requires the ATM's keypadHandle and cashDispenserHandle, and a Deposit (lines 124125) requires the ATM's keypadHandle and depositSlotHandle. We discuss the transaction classes in more detail in Sections J.9J.12. After executing a transaction (line 86 in method PerformTransactions), userExited remains False and the While loop in lines 7595 repeats, returning the user to the main menu. However, if a user does not perform a transaction and instead selects the main menu option to exit, line 90 sets userExited to true causing the condition in line 75 of the While loop (Not userExited) to become False. This While is the final statement of method PerformTransactions, so control returns to line 42 of the calling method Run. If the user enters an invalid main menu selection (i.e., not an integer in the range 14), lines 9293 display an appropriate error message, userExited (as set in line 72) remains False and the user returns to the main menu to try again. When method PerformTransactions returns control to method Run, the user has chosen to exit the system, so lines 4243 reset the ATM's attributes userAuthenticated and currentAccountNumber to False and 0, respectively, to prepare for the next ATM user. Line 44 displays a goodbye message to the current user before the ATM welcomes the next user. |