Navigation:  Tutorials > Creating a GUI Application > Designing the Domain Models >

PersonalAccount

Previous pageReturn to chapter overviewNext page

Let's now create a class to represent each account.

Model subclass: #PersonalAccount

instanceVariableNames: 'name accountNumber initialBalance transactions currentBalance'

classVariableNames: ''

poolDictionaries: ''

 

Each account instance holds some details about the account, such as the name, the account number and the initial balance, together with a list of all the transactions on the account. These variables obviously require initialization to place an instance into a known state.

initialize

       "Private - Initialize the receiver"

 

       name := 'New account'.

       initialBalance := currentBalance := 0.0.

       transactions := ListModel on:

               (SortedCollection sortBlock: [:x :y | x date <= y date])

 

Once again our list is to be a ListModel, but this time it wraps a SortedCollection capable of sorting the account objects that it holds based on their dates.

Now add the following accessor methods.

accountNumber

       "Answer the account number of the receiver"

       ^accountNumber.

 

accountNumber: aString

       "Set the account number of the receiver to aString"

       accountNumber := aString.

 

currentBalance

       "Answer the calculated current balance of the receiver."

       ^currentBalance

 

currentBalance: aNumber

       "Set the current balance of the receiver to aNumber."

       currentBalance := aNumber.

       self trigger: #currentBalanceChanged.

 

initialBalance

       "Answer the account initial balance of the receiver"

       ^initialBalance.

 

initialBalance: aNumber

       "Set the account initial balance of the receiver to aNumber"

       initialBalance := aNumber.

       self calculateCurrentBalance

 

name

       "Answer the account name of the receiver"

       ^name.

 

name: aString

       "Set the account name of the receiver to aString"

       name := aString.

 

transactions

       "Answer the transactions collection"

       ^transactions.

 

Again there is no need to provide a method to set the transactions ListModel.

The following methods add behaviour to the class.

printOn: aStream

       "Append, to aStream, a String whose characters are a description of the

       receiver as a developer would want to see it."

 

       self basicPrintOn: aStream.

       aStream nextPut: $(.

       self name displayOn: aStream.

       aStream nextPut: $,.

       self accountNumber displayOn: aStream.

       aStream nextPut: $,.

       self currentBalance displayOn: aStream.

       aStream nextPut: $).

 

displayOn: aStream

       "Append, to aStream, a String whose characters are a description of the

       receiver as a user would want to see it."

 

       self name displayOn: aStream.

       aStream nextPut: $-.

       self accountNumber displayOn: aStream.

 

addTransaction: aPersonalAccountTransaction

       "Add aPersonalAccountTransaction to the collection of transactions owned by the receiver.

       Answers aPersonalAccountTransaction"

 

       self transactions add: aPersonalAccountTransaction.

       self calculateCurrentBalance.

       ^aPersonalAccountTransaction.

 

removeTransaction: aPersonalAccountTransaction

       "Remove aPersonalAccountTransaction from the collection of transactions

       owned by the receiver. Answers aPersonalAccountTransaction"

       self transactions remove: aPersonalAccountTransaction.

       self calculateCurrentBalance.

       ^aPersonalAccountTransaction.

 

calculateCurrentBalance

       "Calculate and set the current balance of the receiver. Add the total

       of all the actual amounts to the initial balance"

 

       | balance |

       balance := self transactions inject: self initialBalance into: [:total :each |

               total + each actualAmount ].

       self currentBalance: balance.