Flylib.com

Books Software

 
 
 

Appendix J. ATM Case Study Code


[Page 1527]

Appendix J. ATM Case Study Code

Section J.1.  ATM Case Study Implementation

Section J.2.  Class ATM

Section J.3.  Class Screen

Section J.4.  Class Keypad

Section J.5.  Class CashDispenser

Section J.6.  Class DepositSlot

Section J.7.  Class Account

Section J.8.  Class BankDatabase

Section J.9.  Class Transaction

Section J.10.  Class BalanceInquiry

Section J.11.  Class Withdrawal

Section J.12.  Class Deposit

Section J.13.  Class ATMCaseStudy

Section J.14.  Wrap-Up



[Page 1527 ( continued )]

J.1. ATM Case Study Implementation

This appendix contains the complete working implementation of the ATM system that we designed in the nine "Software Engineering Case Study" sections in Chapters 1, 39 and 11. The implementation comprises 655 lines of C# code. We consider the 11 classes in the order in which we identified them in Section 4.11 (with the exception of TRansaction , which was introduced in Chapter 11 as the base class of classes BalanceInquiry, Withdrawal and Deposit ):

  • ATM

  • Screen

  • Keypad

  • CashDispenser

  • DepositSlot

  • Account

  • BankDatabase

  • transaction

  • BalanceInquiry

  • Withdrawal

  • Deposit

We apply the guidelines discussed in Section 9.17 and Section 11.9 to code these classes based on how we modeled them in the UML class diagrams of Fig. 11.21 and Fig. 11.22. To develop the bodies of class methods , we refer to the activity diagrams presented in Section 6.10 and the communication and sequence diagrams presented in Section 8.14. Note that our ATM design does not specify all the program logic and may not specify all the attributes and operations required to complete the ATM implementation. This is a normal part of the object-oriented design process. As we implement the system, we complete the program logic and add attributes and behaviors as necessary to construct the ATM system specified by the requirements document in Section 3.10.


[Page 1528]

We conclude the discussion by presenting a test harness ( ATMCaseStudy in Section J.13) that creates an object of class ATM and starts it by calling its Run method. Recall that we are developing a first version of the ATM system that runs on a personal computer and uses the keyboard and monitor to approximate the ATM's keypad and screen. Also, we simulate the actions of the ATM's cash dispenser and deposit slot. We attempt to implement the system so that real hardware versions of these devices could be integrated without significant code changes. [ Note: For the purpose of this simulation, we have provided two predefined accounts in class BankDatabase . The first account has the account number 12345 and the PIN 54321. The second account has the account number 98765 and the PIN 56789. You should use these accounts when testing the ATM.]



[Page 1528 ( continued )]

J.2. Class ATM

Class ATM (Fig. J.1) represents the ATM as a whole. Lines 511 implement the class's attributes. We determine all but one of these attributes from the UML class diagrams of Fig. 11.21 and Fig. 11.22. Line 5 declares the bool attribute userAuthenticated from Fig. 11.22. Line 6 declares an attribute not found in our UML design int attribute currentAccountNumber , which keeps track of the account number of the current authenticated user . Lines 711 declare reference-type instance variables corresponding to the ATM class's associations modeled in the class diagram of Fig. 11.21. 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.

1



// ATM.cs



2



// Represents an automated teller machine.



3



public class


ATM

4

{

5



private bool


userAuthenticated;


// true if user is authenticated



6



private int


currentAccountNumber;


// user's account number



7



private


Screen screen;


// reference to ATM's screen



8



private


Keypad keypad;


// reference to ATM's keypad



9



private


CashDispenser cashDispenser;


// ref to ATM's cash

dispenser




10



private


DepositSlot depositSlot;


// reference to ATM's deposit slot



11



private


BankDatabase bankDatabase;


// ref to account

info

database



12


13



// enumeration that represents main menu options



14



private enum


MenuOption

15

{

16



BALANCE_INQUIRY


=


1


,

17



WITHDRAWAL


=


2


,

18



DEPOSIT


=


3


,

19



EXIT_ATM


=


4



20

}


// end enum MenuOption



21


[Page 1529]

22



// parameterless constructor initializes instance variables



23



public


ATM()

24

{

25

userAuthenticated =


false


;


// user is not authenticated to start



26

currentAccountNumber =




;


// no current account number to start



27

screen =


new


Screen();


// create screen



28

keypad =


new


Keypad();


// create keypad



29

cashDispenser =


new


CashDispenser();


// create cash dispenser



30

depositSlot =


new


DepositSlot();


// create deposit slot



31

bankDatabase =


new


BankDatabase();


// create account info database



32

}


// end constructor



33


34



// start ATM



35



public void


Run()

36

{

37



// welcome and authenticate users; perform transactions



38



while


(


true


)


// infinite loop



39

{

40



// loop while user is not yet authenticated



41



while


( !userAuthenticated )

42

{

43

screen.DisplayMessageLine(


"\nWelcome!"


);

44

AuthenticateUser();


// authenticate user



45

}


// end while



46


47

PerformTransactions();


// for authenticated user



48

userAuthenticated =


false


;


// reset before

next

ATM session



49

currentAccountNumber =




;


// reset before next ATM session



50

screen.DisplayMessageLine(


"\nThank you!

Goodbye

!"


);

51

}


// end while



52

}


// end method Run



53


54



// attempt to authenticate user against database



55



private void


AuthenticateUser()

56

{

57



// prompt for account number and input it from user



58

screen.DisplayMessage(


"\nPlease enter your account number: "


);

59



int


accountNumber = keypad.GetInput();

60


61



// prompt for PIN and input it from user



62

screen.DisplayMessage(


"\nEnter your PIN: "


);

63



int


pin = keypad.GetInput();

64


65



// set userAuthenticated to boolean value returned by database



66

userAuthenticated =

67

bankDatabase.AuthenticateUser( accountNumber, pin );

68


69



// check whether authentication succeeded



70



if


( userAuthenticated )

71

currentAccountNumber = accountNumber;


// save user's account #



[Page 1530]

72



else



73

screen.DisplayMessageLine(

74



"Invalid account number or PIN. Please try again."


);

75

}


// end method AuthenticateUser



76


77



// display the main menu and perform transactions



78



private void


PerformTransactions()

79

{

80

Transaction currentTransaction;


// transaction being

processed




81



bool


userExited =


false


;


// user has not

chosen

to exit



82


83



// loop while user has not chosen exit option



84



while


( !userExited )

85

{

86



// show main menu and get user selection



87



int


mainMenuSelection = DisplayMainMenu();

88


89



// decide how to proceed based on user's menu selection



90



switch


( ( MenuOption ) mainMenuSelection )

91

{

92



// user chooses to perform one of three transaction types



93



case




MenuOption.BALANCE_INQUIRY


:

94



case




MenuOption.WITHDRAWAL


:

95



case




MenuOption.DEPOSIT


:

96



// initialize as new object of chosen type



97

currentTransaction =

98

CreateTransaction( mainMenuSelection );

99

currentTransaction.Execute();


// execute transaction



100



break


;

101



case




MenuOption.EXIT_ATM


:


// user chose to terminate session



102

screen.DisplayMessageLine(


"\nExiting the system..."


);

103

userExited =


true


;


// this ATM session should end



104



break


;

105



default


:


// user did not enter an integer from 1-4



106

screen.DisplayMessageLine(

107



"\nYou did not enter a valid selection. Try again."


);

108



break


;

109

}


// end switch



110

}


// end while



111

}


// end method PerformTransactions



112


113



// display the main menu and return an input selection



114



private int


DisplayMainMenu()

115

{

116

screen.DisplayMessageLine(


"\nMain menu:"


);

117

screen.DisplayMessageLine(


"1 - View my balance"


);

118

screen.DisplayMessageLine(


"2 - Withdraw cash"


);

119

screen.DisplayMessageLine(


"3 - Deposit funds"


);

120

screen.DisplayMessageLine(


"4 - Exit\n"


);

121

screen.DisplayMessage(


"Enter a choice: "


);

122



return


keypad.GetInput();


// return user's selection



123

}


// end method DisplayMainMenu



[Page 1531]

124


125



// return object of specified Transaction derived class



126



private


Transaction CreateTransaction(


int


type )

127

{

128

Transaction temp =


null


;


// null Transaction reference



129


130



// determine which type of Transaction to create



131



switch


( ( MenuOption ) type )

132

{

133



// create new BalanceInquiry transaction



134



case




MenuOption.BALANCE_INQUIRY


:

135

temp =


new


BalanceInquiry( currentAccountNumber,

136

screen, bankDatabase);

137



break


;

138



case




MenuOption.WITHDRAWAL


:


// create new Withdrawal transaction



139

temp =


new


Withdrawal( currentAccountNumber, screen,

140

bankDatabase, keypad, cashDispenser);

141



break


;

142



case




MenuOption.DEPOSIT


:


// create new Deposit transaction



143

temp =


new


Deposit( currentAccountNumber, screen,

144

bankDatabase, keypad, depositSlot);

145



break


;

146

}


// end switch



147


148



return


temp;

149

}


// end method CreateTransaction



150

}


// end class ATM



Lines 1420 declare an enumeration that corresponds to the four options in the ATM's main menu (i.e., balance inquiry, withdrawal, deposit and exit). Lines 2332 declare class ATM 's constructor, which initializes the class's attributes. When an ATM object is first created, no user is authenticated, so line 25 initializes userAuthenticated to false . Line 26 initializes currentAccountNumber to because there is no current user yet. Lines 2730 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 31 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 Operation

The class diagram of Fig. 11.22 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., class ATMCaseStudy ; Section J.13) to tell the ATM to run. ATM method Run (lines 3552) uses an infinite loop (lines 3851) 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 exits, the ATM resets itself, displays a goodbye message and restarts the process for the next user. 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 can exit the system, but cannot turn off the ATM completely.


[Page 1532]

Inside method Run 's infinite loop, lines 4145 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 !userAuthenticated is true ). Line 43 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 1417 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 44 invokes class ATM 's private utility method AuthenticateUser (declared in lines 5575) to attempt to authenticate the user.

Figure J.2. Class Screen represents the screen of the ATM.
(This item is displayed on pages 1534 - 1535 in the print version)

1



// Screen.cs



2



// Represents the screen of the ATM



3



using


System;

4


5



public class


Screen

6

{

7



// displays a message without a terminating

carriage

return



8



public void


DisplayMessage(


string


message )

9

{

10

Console.Write( message );

11

}


// end method DisplayMessage



12


13



// display a message with a terminating carriage return



14



public void


DisplayMessageLine(


string


message )

15

{

16

Console.WriteLine( message );

17

}


// end method DisplayMessageLine



18


[Page 1535]

19



// display a dollar amount



20



public void


DisplayDollarAmount(


decimal


amount )

21

{

22

Console.Write(


"{0:C}"


, amount );

23

}


// end method DisplayDollarAmount



24

}


// end class Screen



Authenticating the User

We refer to the requirements document to determine the steps necessary to authenticate the user before allowing transactions to occur. Line 58 of method AuthenticateUser invokes method DisplayMessage of the ATM 's screen to prompt the user to enter an account number. Line 59 invokes method GetInput of the ATM 's keypad to obtain the user's input, then stores this integer in local variable accountNumber . Method AuthenticateUser next prompts the user to enter a PIN (line 62), and stores the PIN in local variable pin (line 63). Next, lines 6667 attempt to authenticate the user by passing the accountNumber and pin entered by the user to the bankDatabase 's AuthenticateUser method. Class ATM sets its userAuthenticated attribute to the bool value returned by this method userAuthenticated becomes true if authentication succeeds (i.e., the accountNumber and pin match those of an existing Account in bankDatabase ) and remains false otherwise . If userAuthenticated is true , line 71 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 7374 call the screen '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 cannot authenticate the user, currentAccountNumber remains .

After method Run attempts to authenticate the user (line 44), if userAuthenticated is still false (line 41), the while loop body (lines 4145) executes again. If userAuthenticated is now true , the loop terminates, and control continues with line 47, which calls class ATM 's private utility method PerformTransactions .

Performing Transactions

Method PerformTransactions (lines 78111) carries out an ATM session for an authenticated user. Line 80 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.21 currentTransaction . Line 81 declares another local variablea bool called userExited that keeps track of whether the user has chosen to exit. This variable controls a while loop (lines 84110) that allows the user to execute an unlimited number of transactions before choosing to exit. Within this loop, line 87 displays the main menu and obtains the user's menu selection by calling ATM utility method DisplayMainMenu (declared in lines 114123). 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 87 stores the user's selection, returned by DisplayMainMenu , in local variable mainMenuSelection .


[Page 1533]

After obtaining a main menu selection, method PerformTransactions uses a switch statement (lines 90109) to respond to the selection appropriately. If mainMenuSelection is equal to the underlying value of any of the three enum members representing transaction types (i.e., if the user chose to perform a transaction), lines 9798 call utility method CreateTransaction (declared in lines 126149) 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 99 invokes method Execute of this transaction to execute it. We 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. For example, if the user chooses to perform a balance inquiry, ( MenuOption ) mainMenuSelection (line 90) matches the case label MenuOption.BALANCE_INQUIRY , and CreateTransaction returns a BalanceInquiry object (lines 9798). Thus, currentTransaction refers to a BalanceInquiry and invoking currentTransaction.Execute() (line 99) results in BalanceInquiry 's version of Execute being called polymorphically.

Creating Transactions

Method CreateTransaction (lines 126149) uses a switch statement (lines 131146) 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 126) receives one of the values MenuOption.BALANCE_INQUIRY , MenuOption.WITHDRAWAL or MenuOption.DEPOSIT . Each case in the switch 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 135136) requires only the account number of the current user and references to the ATM 's screen and the bankDatabase . In addition to these parameters, a Withdrawal (lines 139140) requires references to the ATM 's keypad and cashDispenser , and a Deposit (lines 143144) requires references to the ATM 's keypad and depositSlot . We discuss the transaction classes in detail in Sections J.9J.12.

After executing a transaction (line 99 in method PerformTransactions ), userExited remains false , and the while loop in lines 84110 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 103 sets userExited to TRue , causing the condition in line 84 of the while loop ( !userExited ) to become false . This while is the final statement of method PerformTransactions , so control returns to line 47 of the calling method Run . If the user enters an invalid main menu selection (i.e., not an integer in the range 14), lines 106107 display an appropriate error message, userExited remains false (as set in line 81) and the user returns to the main menu to try again.


[Page 1534]

When method PerformTransactions returns control to method Run , the user has chosen to exit the system, so lines 4849 reset the ATM 's attributes userAuthenticated and currentAccountNumber to false and , respectively, to prepare for the next ATM user. Line 50 displays a goodbye message to the current user before the ATM welcomes the next user.