Sponsored Link •
|
Summary
The example of a bank account class is a canonical one in the object oriented programming (OOP) literature. Here are my thoughts on how the bank account problem should be approached.
Advertisement
|
The object-oriented bank account example is a common demonstration of OOP by attempting to model a bank account class. Eric Theriault referenced a talk on his blog by Kevlin Henney which brought the old chestnut to the forefront of my consciousness again. Here is the quote from Eric's blog which I find rather enlightened.
... one of my courses at OOPSLA has been with Kevlin Henney, and he reminds us that when developing object oriented software, the getters and setters are generally not the proper abstraction for an object. More specifically, his example was for a Bank Account, where the methods provided are getBalance() and setBalance(). While this is a very powerful interface, this is not the proper abstraction to use, especially since in this case, the object could change state between the initial get and the final set. As such, a better interface would be a method to acquire the current balance, a method to withdraw funds, and a method to deposit funds. In addition to being a more coherent interface, the business logic can easily be applied in this design.
There is no argument from me that Get and Set is a naive interface to a multi-threaded bank account class. It is pretty safe to expect that a bank account class is going to be multi-threaded, as most models of a transactional system probably should be.
The issue is, if we only provided locksafe Deposit / Withdraw, how do we deal with something like deposit interest? We could conceivably provide another function for DepositInterest. The next problem would be a bank fee scheme which depends on the amount of money in the account. Again this also has to be thread safe. But what happens is we are overloading the repsonsibility of the account class.
What makes the most sense is to keep the BankAccount class as simple as possible. Something like: ViewBalance, GetBalanceAndLock, SetBalanceAndUnlock. Strictly speaking nothing else is needed, all other functionality can be provided from that basis. More sophisticated functionality can be implemented in very simple account accessor classes. Withdraw and Deposit for instance chould be separated into a new class which could be descirbed as below:
TellerAccountAccessor { PayBill(amount) { cur = account.GetBalanceAndLock() account.SetBalanceAndUnlock(cur - amount); } Withdraw(amount) { cur = account.GetBalanceAndLock() account.SetBalanceAndUnlock(cur - amount); } Deposit(amount) { cur = account.GetBalanceAndLock() account.SetBalanceAndUnlock(cur + amount); } BankAccount account; }
Since I brought up the concerns of interest and fees it would make sense to have another class which provides that functionality:
BankAccountAccessor { DeductFees(exemption, fees) { cur = account.GetBalanceAndLock(); if (cur < exemption) { cur = cur - fees; } SetBalanceAndUnlock(cur); } DepositInterest(interest_rate) { cur = account.GetBalanceAndLock(); interest = cur * interest_rate; cur = cur + interest; SetBalanceAndUnlock(cur); } BankAccount account; }
I invite the reader to share their thoughts on the subject. Even the simplest of basic object oriented designs can make for interesting and informative discussion.
Have an opinion? Readers have already posted 24 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.
Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com. |
Sponsored Links
|