23.4.7. Class BankDatabase

Class BankDatabase (Figs. 23.2623.27) models the bank’s database with which the ATM interacts to access and modify a user’s account information. The class definition (Fig. 23.26) declares function prototypes for the class’s constructor and several member functions. We discuss these momentarily. The class definition also declares the BankDatabase’s data members. We determine one data member for class BankDatabase based on its composition relationship with class Account. Recall from Fig. 23.10 that a BankDatabase is composed of zero or more objects of class Account. Line 24 of Fig. 23.26 implements data member accounts—a vector of Account objects—to implement this composition relationship. Lines 6–7 allow us to use vector in this file. Line 27 contains the function prototype for a private utility function getAccount that allows the member functions of the class to obtain a pointer to a specific Account in the accounts vector.


 1   // BankDatabase.h
 2   // BankDatabase class definition. Represents the bank's database.
 3   #ifndef BANK_DATABASE_H
 4   #define BANK_DATABASE_H
 5
 6   #include <vector> // class uses vector to store Account objects
 7   using namespace std;
 8
 9   #include "Account.h" // Account class definition
10
11   class BankDatabase
12   {
13   public:
14      BankDatabase(); // constructor initializes accounts
15
16      // determine whether account number and PIN match those of an Account
17      bool authenticateUser( int, int ); // returns true if Account authentic
18
19      double getAvailableBalance( int ); // get an available balance
20      double getTotalBalance( int ); // get an Account's total balance
21      void credit( int, double ); // add amount to Account balance
22      void debit( int, double ); // subtract amount from Account balance
23   private:
24      vector< Account > accounts; // vector of the bank's Accounts
25
26      // private utility function
27      Account * getAccount( int ); // get pointer to Account object
28   }; // end class BankDatabase
29
30   #endif // BANK_DATABASE_H


Fig. 23.26. BankDatabase class definition.


 1   // BankDatabase.cpp
 2   // Member-function definitions for class BankDatabase.
 3   #include "BankDatabase.h" // BankDatabase class definition
 4
 5   // BankDatabase default constructor initializes accounts
 6   BankDatabase::BankDatabase()
 7   {
 8      // create two Account objects for testing
 9      Account account1( 12345, 54321, 1000.0, 1200.0 );
10      Account account2( 98765, 56789, 200.0, 200.0 );
11
12      // add the Account objects to the vector accounts
13      accounts.push_back( account1 ); // add account1 to end of vector
14      accounts.push_back( account2 ); // add account2 to end of vector
15   } // end BankDatabase default constructor
16
17   // retrieve Account object containing specified account number
18   Account * BankDatabase::getAccount( int accountNumber )
19   {
20      // loop through accounts searching for matching account number
21      for ( size_t i = 0; i < accounts.size(); i++ )
22      {
23         // return current account if match found
24         if ( accounts[ i ].getAccountNumber() == accountNumber )
25            return &accounts[ i ];
26      } // end for
27
28      return NULL; // if no matching account was found, return NULL
29   } // end function getAccount
30
31   // determine whether user-specified account number and PIN match
32   // those of an account in the database
33   bool BankDatabase::authenticateUser( int userAccountNumber,
34      int userPIN )
35   {
36      // attempt to retrieve the account with the account number
37      Account * const userAccountPtr = getAccount( userAccountNumber );
38
39      // if account exists, return result of Account function validatePIN
40      if ( userAccountPtr != NULL )
41         return userAccountPtr->validatePIN( userPIN );
42      else
43         return false; // account number not found, so return false
44   } // end function authenticateUser
45
46   // return available balance of Account with specified account number
47   double BankDatabase::getAvailableBalance( int userAccountNumber )
48   {
49      Account * const userAccountPtr = getAccount( userAccountNumber );
50      return userAccountPtr->getAvailableBalance();
51   } // end function getAvailableBalance
52
53   // return total balance of Account with specified account number
54   double BankDatabase::getTotalBalance( int userAccountNumber )
55   {
56      Account * const userAccountPtr = getAccount( userAccountNumber );
57      return userAccountPtr->getTotalBalance();
58   } // end function getTotalBalance
59
60   // credit an amount to Account with specified account number
61   void BankDatabase::credit( int userAccountNumber, double amount )
62   {
63      Account * const userAccountPtr = getAccount( userAccountNumber );
64      userAccountPtr->credit( amount );
65   } // end function credit
66
67   // debit an amount from Account with specified account number
68   void BankDatabase::debit( int userAccountNumber, double amount )
69   {
70      Account * const userAccountPtr = getAccount( userAccountNumber );
71      userAccountPtr->debit( amount );
72   } // end function debit


Fig. 23.27. BankDatabase class member-function definitions.

BankDatabase Class Member-Function Definitions

Figure 23.27 contains the member-function definitions for class BankDatabase. We implement the class with a default constructor (lines 6–15) that adds Account objects to data member accounts. For the sake of testing the system, we create two new Account objects with test data (lines 9–10), then add them to the end of the vector (lines 13–14). The Account constructor has four parameters—the account number, the PIN assigned to the account, the initial available balance and the initial total balance.

Recall that class BankDatabase serves as an intermediary between class ATM and the actual Account objects that contain users’ account information. Thus, the member functions of class BankDatabase do nothing more than invoke the corresponding member functions of the Account object belonging to the current ATM user.

We include private utility function getAccount (lines 18–29) to allow the BankDatabase to obtain a pointer to a particular Account within vector accounts. To locate the user’s Account, the BankDatabase compares the value returned by member function getAccountNumber for each element of accounts to a specified account number until it finds a match. Lines 21–26 traverse the accounts vector. If the account number of the current Account (i.e., accounts[ i ]) equals the value of parameter accountNumber, the member function immediately returns the address of the current Account (i.e., a pointer to the current Account). If no account has the given account number, then line 28 returns NULL. Note that this member function must return a pointer, as opposed to a reference, because there is the possibility that the return value could be NULLa reference cannot be NULL, but a pointer can.

Note that vector function size (invoked in the loop-continuation condition in line 21) returns the number of elements in a vector as a value of type size_t (which is usually unsigned int). As a result, we declare the control variable i to be of type size_t, too. On some compilers, declaring i as an int would cause the compiler to issue a warning message, because the loop-continuation condition would compare a signed value (i.e., an int) and an unsigned value (i.e., a value of type size_t).

Member function authenticateUser (lines 33–44) proves or disproves the an ATM user’s identity. This function takes a user-specified account number and user-specified PIN as arguments and indicates whether they match the account number and PIN of an Account in the database. Line 37 calls utility function getAccount, which returns either a pointer to an Account with userAccountNumber as its account number or NULL to indicate that userAccountNumber is invalid. We declare userAccountPtr to be a const pointer because, once the member function aims this pointer at the user’s Account, the pointer should not change. If getAccount returns a pointer to an Account object, line 41 returns the bool value returned by that object’s validatePIN member function. BankDatabase’s authenticateUser member function does not perform the PIN comparison itself—rather, it forwards userPIN to the Account object’s validatePIN member function to do so. The value returned by Account member function validatePIN indicates whether the user-specified PIN matches the PIN of the user’s Account, so member function authenticateUser simply returns this value to the client of the class (i.e., ATM).

BankDatabase trusts the ATM to invoke member function authenticateUser and receive a return value of true before allowing the user to perform transactions. BankDatabase also trusts that each Transaction object created by the ATM contains the valid account number of the current authenticated user and that this is the account number passed to the remaining BankDatabase member functions as argument userAccountNumber. Member functions getAvailableBalance (lines 47–51), getTotalBalance (lines 54–58), credit (lines 61–65) and debit (lines 68–72) therefore simply retrieve a pointer to the user’s Account object with utility function getAccount, then use this pointer to invoke the appropriate Account member function on the user’s Account object. We know that the calls to getAccount within these member functions will never return NULL, because userAccountNumber must refer to an existing Account. Note that getAvailableBalance and getTotalBalance return the values returned by the corresponding Account member functions. Also, credit and debit simply redirect parameter amount to the Account member functions they invoke.

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

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