Part 14: The complete BANK system

 
 
 

14.1 Specification

        A banking system has many customers. Each customer may have a savings account, a cheque account, and an investment account, one account of each type. The bank offers access to cheque and savings accounts through an interactive menu like that seen in an automatic teller machine (ATM); an investment account cannot be accessed through the ATM. Savings and investment accounts accrue daily interest, paid on the current balance; cheque accounts do not accrue interest.

        A positive amount may be deposited in an account or withdrawn from an account. A withdrawal from a savings account decrements the balance by that amount; there are no charges or penalties for a savings account. A successful withdrawal from a cheque account costs 50 cents. An unsuccessful withdrawal from a cheque account costs $5. The balance of an account cannot be negative.

        A savings account gets daily interest; the interest rate is 4.5% a year. A cheque account gets no interest. An investment account is created with an initial balance of at least $1000, and accrues daily interest for a period of 3, 6, or 12 months. A 3-month investment account has an annual interest rate of 5.5%, a 6-month account has a 6.0% rate, and a 12-month account 6.5%. When the account matures at the end of the period, the total amount is transferred into the customer's cheque account.

        The bank system runs for an extended period. At the start of each day, a bank teller creates new customers, and new accounts for existing customers. Each customer has a unique integer key; successive integers are used for each new customer. Customers and accounts are never deleted from the bank. The ATM then runs all day, handling multiple customers. To use the ATM, a customer enters their unique key (this simulates putting a card into the ATM) and their password, chooses an account, then chooses commands from the menu. Menu commands are read and executed until the customer finishes; the ATM then waits for the next customer. A special key of 666 exits the ATM system for the day. Interest is then added to all savings and investment accounts. Entry of the special key value of 999 into the ATM shuts down the whole system. The bank data is stored to file when the system shuts down, and is retrieved from file when the system starts up again.

        A customer is allowed three attempts to login to the ATM by entering a valid password. If no correct password is entered after three attempts, then the ATM system rejects the login attempt and asks for a new customer identifier. If the password is correct, then the customer is shown a menu of account choices, and the system reads and executes the choices. Any number of transactions may be made; processing on the account continues until the customer chooses to exit that account. Multiple accounts may be chosen and used within a single ATM session.

        The ATM menu choices (upper or lower case) are
 
 
        D Deposit
        W Withdraw up to the total amount in the account
        B Show the balance
        Q Quit the system
        H Help: Show themenu choices

 
 
 

14.2 Inheritance charts

        The first inheritance chart shows the inheritance for a storable, keyed list, and for an element of that list, a customer.
 


 
 
 

        The second inheritance chart shows the inheritance structure of the bank accounts.
 


 
 
 
 

14.3 Client charts

        The first client chart shows the overall structure of the system that uses a list of customers.
 


 

        The second part of the client chart shows the use within a customer.


 
 

14.4 Class diagrams

        The first set of three diagrams shows the overall structure of the banking system.


 

        The next set of five diagrams shows the customer subsystem.


 

        The next set of four charts shows the account container class, and the non-ATM account classes.


 

        The final set of four diagrams shows the ATM account classes.


 
 

14.5 Class listings

        The Eiffel code for the BANK system is shown on the following pages. The classes are listed in client order, and within this in inheritance order. The client and inheritance orders are shown below, taken from the client and inheritance charts. A total listing order is then given.

Client order
 
BANK TELLER KEY_LIST CUSTOMER PASSWORD
ACCOUNTS SAVINGS
CHEQUE
INVEST
ATM KEY_LIST CUSTOMER PASSWORD
ACCOUNTS SAVINGS
CHEQUE
INVEST

 

Inheritance order
 
KEYED CUSTOMER
PERSON
ACCOUNT INTEREST INVEST
ACCOUNT MENU INTERACCT INTEREST SAVINGS
ACCOUNT MENU INTERACCT CHEQUE

 

Listing order

BANK
TELLER
ATM
KEY_LIST
KEYED
PERSON
CUSTOMER
PASSWORD
ACCOUNTS
ACCOUNT
INTEREST
INVEST
MENU
INTERACCT
SAVINGS
CHEQUE


class BANK

inherit
        STORABLE

creation
        make

feature {NONE}
        file_name: STRING is "patrons.dat"
        patrons: KEY_LIST[CUSTOMER]
        teller: TELLER
        atm: ATM

        make is
                        -- make or retrieve the list of customers
                        -- make the ATM and TELLER, pass the customer list
                        -- run the ATM and teller until system shuts down
              do
                      retrieve
                      !!teller.make (patrons)
                      !!atm.make (patrons)
                      run
--                   store
                      io.putstring ("%N%NExit banking system%N")
              end -- make

        retrieve is
                        -- make or retrieve the list of customers
              local file: RAW_FILE
              do
                      !!file.make (file_name)
                      if file.exists then
                              file.open_read
                              patrons ?= retrieved (file)
                              file.close
                              show_retrieved
                      end
                      if patrons = Void then !!patrons.make end
              end -- retrieve

        show_retrieved is
                        -- show the number of customers retrieved
              do
                      io.putstring ("%N%T**** ")
                      io.putint (patrons.count)
                      io.putstring (" records read from file ****%N")
              end -- show_retrieved

        run is
                        -- each day, run the teller then the atm subsystems
                        -- at the end of a day, add interest and check investments
              do
                      from
                      until atm.system_finished
                      loop
                              teller.run
                              atm.run
                              end_day
                      end
              end -- run

        end_day is
                        -- add interest for every customer
                        -- add a day to the investment counter
              do
                      from patrons.start
                      until patrons.after
                      loop
                              patrons.item.accounts.end_day
                              patrons.forth
                      end
              end -- end_day

        store is
                        -- store the list of customers
              local file: RAW_FILE
              do
                      !!file.make (file_name)
                      file.open_write
                      patrons.basic_store (file)
                      file.close
              end -- store

end -- class BANK
 

class TELLER

creation {BANK}
        make

feature {NONE}
        patrons: KEY_LIST[CUSTOMER]

feature {BANK}
        make (customers: KEY_LIST[CUSTOMER]) is
                        -- set the patrons to the list of customers
              do patrons := customers end -- make

        run is
                        -- add interest to all accounts
                        -- create new customers
                        -- create new accounts for existing customers
              do
                      show_header
                      new_customers
                      new_accounts
              end -- run

feature {NONE}
        show_header is
                        -- show the teller a nice message
              do
                      io.putstring ("%N")
                      io.putstring ("%N**************************************")
                      io.putstring ("%N* Add new customers and new accounts *")
                      io.putstring ("%N**************************************")
              end

        new_customers is
                        -- add any new customers with their initial accounts
              local patron: CUSTOMER
              do
                      from ask_for_more_customers
                      until no_more
                      loop
                              !!patron.make (patrons.count + 1)
                              patron.add_accounts
                              patrons.extend (patron)
                              ask_for_more_customers
                      end
              end -- new_customers

        ask_for_more_customers is
                        -- prompt the user for more customers, read reply
            &nb