This project is read-only.
Bank account

Category:
Application
Description: Bank account with threadsafe deposit and withdraw feature. This implementation generates the object according to its internal state.
Code:
type IAccount = 
abstract Withdraw : int -> unit
abstract Deposit : int -> unit
type AccountInfo = {
Balance: int
}

type BankAccount (initialBalance) =
let mutable accountInfo = { Balance = initialBalance }
member this.AccountInfo
with get() = accountInfo
member this.GetCommand() =
if accountInfo.Balance >= 0 then
{ new IAccount with
member this.Withdraw(amount) =
if (amount > accountInfo.Balance) then printfn "cannot withdraw"
else accountInfo <- { accountInfo with Balance = accountInfo.Balance - amount }
member this.Deposit(amount) =
accountInfo <- { accountInfo with Balance = accountInfo.Balance + amount } }
else
{ new IAccount with
member this.Withdraw(amount) =
printfn "not enough fund"
member this.Deposit(amount) =
accountInfo <- { accountInfo with Balance = accountInfo.Balance + amount } }

let Application1() =
let account = BankAccount(-1)
account.GetCommand().Withdraw(1)
account.GetCommand().Deposit(100)
account.GetCommand().Withdraw(5)

Execution Result:
not enough fund

Bank account and access control

Category:
Application
Description: This is a Factory Pattern usage. The function returns different types of object when given different access control level.
Code:
type private BankBase() = 
let mutable accountInfo = { Balance = 0 }
member this.AccountInfo
with get() = accountInfo
member this.Deposit(amount) =
printfn "will deposit %A" amount
accountInfo <- { this.AccountInfo with Balance = this.AccountInfo.Balance + amount }
member this.Withdraw(amount) =
printfn "will withdraw %A" amount
accountInfo <- { this.AccountInfo with Balance = this.AccountInfo.Balance - amount }

type IQueryAccount =
abstract Query : unit -> AccountInfo
type IFullControlAccount =
inherit IQueryAccount
abstract Deposit : int -> unit
abstract Withdraw : int -> unit
type AccessType =
| QueryOnly
| Full

let private createAccess(account:BankBase, ``access type``) =
match ``access type`` with
| QueryOnly -> { new IQueryAccount with
member this.Query() = account.AccountInfo }
| Full -> { new IFullControlAccount with
member this.Deposit(amount) = account.Deposit(amount)
member this.Withdraw(amount) = account.Withdraw(amount)
member this.Query() = account.AccountInfo } :> IQueryAccount

let Application2() =
let account = BankBase()
let access = createAccess(account, AccessType.Full) :?> IFullControlAccount
let queryOnly = createAccess(account, AccessType.QueryOnly)
printfn "balance is %d" (queryOnly.Query().Balance)
access.Deposit(100)
printfn "balance is %d" (queryOnly.Query().Balance)





Execution Result:
balance is 0
will deposit 100
balance is 100

Last edited Sep 13, 2011 at 12:13 AM by ttliu2000, version 2

Comments

No comments yet.