Extend the system in two ways:
1. Guard the system against invalid input. If a value is invalid, then reject it (do not use the value). A much better idea is to ask the user for a better value, but this soluton must wait the next part of the case study, where loops are covered.
2. Us e the gender
code to type out "Mr. " or "Ms. ".
Three guards are needed on an account: |
The initial balance must be positive. |
A deposit must be positive. |
A withdrawal must be positive, and not less than the balance. |
One guard is needed on the customer: |
the valid input values for a gender are M, m, F, and f. |
A function enough is defined in class ACCOUNT to test if an account has enough money for a withdrawal. The withdraw routine in CUSTOMER uses enough as a guard on the actions. This function is used by CUSTOMER, because it is the clients responsibility to call the supplier (withdraw) correctly.
CUSTOMER must be able to test a precondition on an ACCOUNT routine before it is called, so the pre-conditions never fail. A function positive is therefore added to CUSTOMER.
A test cannot be used to guard the get_balance routine, because that routine has no arguments to guard. An invalid initial balance must be rejected. The routine is therefore split into two parts named read and set; read reads in a value from the user and tests it, and set uses this value if it is valid. The read routine is placed in CUSTOMER, and the set in ACCOUNT.
The client chart is unchanged. The class diagram for ACCOUNT is changed to include the new exported feature, enough. The new class diagram for ACCOUNT is shown below.
The changed and added code in classes CUSTOMER and ACCOUNT
is shown below.
class CUSTOMER
creation {BANK}
make
feature {NONE}
...
get_gender
is
-- read in a gender code, store it if it is valid
do
read_gender
if valid_gender
then gender := io.lastchar
else
io.putstring ("%TValid codes are M, m, F, f.")
io.putstring (" Gender set to M%N")
gender := M
end
end -- get_gender
read_gender
is
-- read in a gender code
do
io.putstring (" Gender (M/F): ")
io.readchar
io.next_line
end -- read_gender
valid_gender:
BOOLEAN is
-- has a valid gender code been entered?
do
inspect io.lastchar.upper
when 'M', 'F' then Result := true
else Result := false
end
end -- valid_gender
show_gender
is
-- show a title indicating the gender
do
inspect gender
when 'M', 'm' then io.putstring ("%NMr. ")
when 'F', 'f' then io.putstring ("%NMs. ")
end
end -- show_gender
...
positive
(amount: REAL): BOOLEAN is
-- is the amount positive?
do
Result := amount > 0
end -- positive
feature {BANK}
make
is
-- create the customer from input data
do
io.putstring ("%NEnter the customer details%N%N")
get_name
get_gender
get_address
get_account
end -- make
get_account
is
-- read in an amount for the balance, set the balance if possible
-- if amount is invalid, set the balance to one cent
do
io.putstring ("%TEnter the initial account balance: $")
io.readreal
if positive (io.lastreal)
then !!account.make (io.lastreal)
else
io.putstring ("%TAmount must be positive. Balance set to $0.01.%N")
!!account.make (0.01)
end
end -- make
show
is
-- show the customer details
do
io.new_line
show_gender
io.putstring (name)
...
end -- show
...
deposit
is
-- read in amount from the user, deposit it if possible
do
io.putstring ("%TEnter the amount to deposit: $")
io.readreal
if positive (io.lastreal)
then account.deposit (io.lastreal)
else io.putstring ("%TAmount must be positive. No deposit made.%N")
end
end -- deposit
withdraw
is
-- read in amount from the user, withdraw it if possible
do
io.putstring ("Enter the amount to withdraw: ")
io.readreal
if positive (io.lastreal)
then if account.enough (io.lastreal)
then account.withdraw (io.lastreal)
else io.putstring ("%TAmount exceeds balance. No withdrawal
made.%N")
else io.putstring ("%TAmount must be positive. No withdrawal
made.%N")
end
end -- withdraw
...
end -- class CUSTOMER
class ACCOUNT
...
feature {NONE}
set_balance
(amount: REAL) is
-- set the balance to amount