The Artima Developer Community
Sponsored Link

Weblogs Forum
OOP Case Study: The Bank Account Class

24 replies on 2 pages. Most recent reply: Aug 21, 2005 12:50 AM by rajwant

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 24 replies on 2 pages [ « | 1 2 ]
Ravi Venkataraman

Posts: 80
Nickname: raviv
Registered: Sep, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 1:29 AM
Reply to this message Reply
Advertisement
James Emerton echoes my feelings exactly.

Time and again programmers complicate the design needlessly, and then wonder why the project gets delayed.

Christopher, I believe, is one of the creators (or sole creator?) of the Heron programming language. His inability to give a simple design for this simple problem leads me to wonder what his programming language is not worthy of any further consideration.

Sorry to be blunt, but, in my opinion, anybody who can not provide a simple design for the Bank Account demo example has no business creating a new language.

Ravi

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 11:28 AM
Reply to this message Reply
> James Emerton echoes my feelings exactly.
>
> Time and again programmers complicate the design
> needlessly, and then wonder why the project gets delayed.

I have significant doubts that there is much room for simplification when designing a logging transactional multi-threaded bank account representation. Rather than throwing all of the repsonsibilities into one single account class I am proposing a design of multiple small classes each with a clear and well-defined role. This kind of approach leads to more flexible designs but the overall complexity I would argue is not in fact more complicated. All of the concerns have to be addressed.

I invite James and Ravi to propose their own simplified alternative designs.

> Christopher, I believe, is one of the creators (or sole
> creator?) of the Heron programming language. His inability
> to give a simple design for this simple problem leads me
> to wonder what his programming language is not worthy of
> any further consideration.

You have not demonstrated how the design can be simplified while still satisfying the requirements proposed previously by Keith Ray.

> Sorry to be blunt, but, in my opinion, anybody who can
> an not provide a simple design for the Bank Account demo
> example has no business creating a new language.

Judging Heron based on this particular design of a bank account class is narrow-minded.

- Christopher

Darryl Mataya

Posts: 9
Nickname: dmataya
Registered: Nov, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 11:50 AM
Reply to this message Reply
James makes a good point – anticipating possible interfaces and objects without a thorough understanding of the business model can lead to excessive complexity and the proverbial hammer looking for a nail to hit. But the reverse is also all too true. Designers often think they know most of the rules. In fact just ask them – its all in their heads!

Business rules are very often exposed in the process of trying to implement an interface. James provides an excellent example when he assumes that a withdrawal is just a negative deposit. To a mathematician this is certainly true. But to a compliance officer at a bank, this is most definitely not the case. A withdrawal is subject to a different set of regulatory rules than a deposit is. Just walk into a US commercial bank and ask to withdraw $10,100 if you want to see it in action.

As far as Christopher’s most recent interface design goes, the transactional approach with various types of transactions is a paradigm that I think works well and in fact gets implemented regularly in banking systems. The only interface visible to an application would be IAccount (and higher), and I don’t even think that the getbalance methods are needed at the IAccount level. The acquisition of a balance is itself a transaction in most of the banking world – for example, what balance does an ATM disclose to you when you want to withdraw cash vs. the balance(s) exposed to a teller with a much higher level of security? The transaction interfaces themselves can be flat as proposed (all derived from ITransaction), or they might work better in a hierarchy where for example you would implement money-out transactions from a base withdrawal class. The best approach would most definitely depend on the specific business and regulatory rules that you were trying to support. But we know from practice that a hierarchical model does work well when an industry is constantly modifying its product line. A home equity line of credit loan is very similar to a mortgage, except for …

I think this thread has met Christopher’s original intention, but probably not in the direction he originally imagined. The design of an object is an artistic process that has to eventually “sell” to someone, and of course it ultimately has to perform on a computational device. But we should never automatically conclude that the design of anything – an object, a syntax, or a language, should be straightforward or obvious. Isn’t this process in fact how good software gets developed?

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 12:23 PM
Reply to this message Reply
I appreciate Darryl defending the design decisions. I think he makes very salient points that are appropriate when we attempt to properly model a banking system.

> I think this thread has met Christopher’s original
> intention, but probably not in the direction he originally
> imagined.

To be honest, this design does not surprise me. It is completely consistent with the simpler design I was proposing earlier, it simply adds new layers of abstraction. The difference is the specificity of the requirements and constraints. The guiding principle here is TSTCPW (The Simplest Thing That Could Possibly Work), and the principle of separation of concerns. Each class should have a clear and well-defined role. In object oriented software design we should not have to rewrite a class to provide a level of specialization to meet new requirements. What is preferable is to introduce new classes which occupy themselves with the new concerns.

James and Ravi brought up points which were correct in the general sense, but in the context of the discussion were somewhat misguided because others in the thread has already established a set of requirements.

If in a job interview someone asked me to simply "provide a representation of a bank account in code" without any other specifications, I would give them the following code, and I would argue that without further specifications it is the only correct response:

  int account; // represents number of cents in account
The issue is that as requirements increase, and the fact that as programmers we can intuit a large number of requirements, as Darryl and others did, this leads to a significantly more sophisticated design.

Throughout the design process the most important thing is that each class has a clear and well-defined role. This improves the chances of re-use of classes, it keeps internal and overall complexity low and allows for maximum flexibility to anticipate changing requirements.

Darryl Mataya

Posts: 9
Nickname: dmataya
Registered: Nov, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 1:28 PM
Reply to this message Reply
> If in a job interview someone asked me to simply "provide
> a representation of a bank account in code" without any
> other specifications, I would give them the following
> code, and I would argue that without further
> specifications it is the only correct response:

Good quiz question! I would have responded that the base representation of an object must reflect its essence:


// Represents a financial asset or obligation belonging to an individual or legal entity and housed by a financial intermediary.
public class account {
private void protect();
}

James Emerton

Posts: 5
Nickname: ephelon
Registered: Oct, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 2:02 PM
Reply to this message Reply
> James and Ravi brought up points which were correct in the
> general sense, but in the context of the discussion were
> somewhat misguided because others in the thread has
> already established a set of requirements.

The only requirement I noted was for a Bank Account class which was thread safe. (A simple global int does not meet this requirement, as it is not thread safe.)

If I was assigned to design a bank account class, and that was the spec I was handed, I would probably send the spec back. Being that I do not work for a bank, (and that I seem to have more knowledge about credit cards than savings accounts) I am not qualified to write a real-world bank account class.

To satisfy the requirements I have seen thus far, and the assumption that an account must have a balance you can see and change in a bankish way...


interface IAccount:
- GetBalance() : int
- AdjustBalance( int )


Anything else you add to this interface is an assumption. I have a rule about assumptions; assume they are wrong.

You will give this design to your customer, and they might say, "What about X?"

You will say, "Yes ma'am, we can add that in the next iteration"

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 9, 2004 2:30 PM
Reply to this message Reply
> The only requirement I noted was for a Bank Account class
> which was thread safe. (A simple global int does not meet
> this requirement, as it is not thread safe.)

I am aware that a global int is not thread safe. Nothing said the int was global. The int example was also for a case where "no other requirements are specified", I did not assume a multi-threaded environment in that case.

> If I was assigned to design a bank account class, and that
> was the spec I was handed,

I am not sure if you were referring to the spec first described in the article or previously in the discussion.

> To satisfy the requirements I have seen thus far, and the
> assumption that an account must have a balance you can see
> and change in a bankish way...
>
> interface IAccount:
> - GetBalance() : int
> - AdjustBalance( int )

I think that is a valid representation of an account. This representation has more or less equal footing as:


interface IAccount
GetBalance();
Withdraw(unsigned int);
Deposit(unsigned int);


Both have the core problem in a mult-threaded environment that it can be desirable to Lock the account between a GetBalance() function and any kind of SetBalance() or AdjustBalance(). For instance if I was to compute and deposit an amount which was a function of the balance as a single atomic operation. If this never occurs then your model is fully adequate.

> Anything else you add to this interface is an assumption.
> I have a rule about assumptions; assume they are wrong.
>
> You will give this design to your customer, and they might
> say, "What about X?"
>
> You will say, "Yes ma'am, we can add that in the next
> iteration"

This is a rather inflexible approach to dealing with customers, which can make it difficult to keep clients happy. I have found in practice that approach to make it hard to get repeat business as a consultant.

- Christopher

Curt Sampson

Posts: 21
Nickname: cjs
Registered: Mar, 2004

Re: OOP Case Study: The Bank Account Class Posted: Nov 10, 2004 12:37 AM
Reply to this message Reply
You're right that these "bank account" classes are entirely the wrong abstraction, but that's the case not from a programmer's point of view but from an accountants. What you are modelling is a bank account *balance*, which as any decent DBA can tell you, should not exist at all, if possble. (It may be necessary in some systems to have one as a performance optimization, in which case you live with the fact that it can be wrong, and you don't use it when it's critically important that you know the real balance at a particular point in time.)

A bank account is not a balance, it's a list of transactions on the account.

Ryan Shriver

Posts: 9
Nickname: rshriver
Registered: Oct, 2002

Re: OOP Case Study: The Bank Account Class Posted: Nov 11, 2004 12:34 AM
Reply to this message Reply
I've enjoyed the discussions for this thread and agree that we've gone well beyond the original scope. I'm the architect (and developer!) for my client and we're in the midst of developing a Java based accounting system for Loans and Leases. It's a product developed for banks and captive finance companies. After a year on the job I'm learning more than I ever could imagine about how accounting systems work. I mention this not try and impress anyone but to give you my frame of reference. Hope you don't consider this overboard :-)

Some observations from my experience:

1. There's no such thing as a 'simple' bank account example, so this really is a hard problem to try and make simple :-) There's subtleties in ever corner.

2. Locking the account while doing things isn't really the issue, I don't believe. Databases support atomic updates. Processing transactions against accounts and recording their effects is the central issue.

3. The single hardest problem in developing banking systems is dealing with the effect of time on money. It's a tricky problem. What happens when a check falls behind someone's desk, three months pass, and they need to post it effective three months ago? Or you need to reverse an expense because the customer complains and the manager agrees? In the real world things don't always go right the first time and sometimes we need to 'correct' history after the fact.

To do this requires you to be able to recreate the snapshot of the account at a specific point in time, apply the right transaction, and then apply all subsequent transactions back against the account to bring it up to date. Then persist the changes in a database transaction on commit, else rollback the transactions affect on the account. The event model where each one creates one or more related transactions greatly simplifies this capability. Especially if the transactions are linked, because reversing parent transactions typically reverse all their children.

This is one model, there are others.

Here's a simplified Transaction interface:

public interface Transaction {
public String type();
public Money amount();
public Date effectiveDate();
public boolean isParent();
public boolean isChild();
public boolean isReversal();
public Transaction parentTransaction();
public List childTransactions();
public List accountingEntries();
public List debits();
public List credits();
public Transaction reverse();
public boolean execute();
}

Then we get into different types of Transactions:

public class Payment implements Transaction {}
public class Adjustment implements Transaction {}
public class Fee implements Transaction {}
public class Expense implements Transaction {}
public class LateCharge extends Expense{}
public class Withdrawl implements Transaction {}
public class Deposit implements Transaction {}

Where each has their rules within execute(); Doing this allows you to treat all these generically as Transactions but allow each to contain different rules.

Then you can add methods to your BankAccount class like this:

public class BankAccount {

private Money principle;
private Interest interest;
private TransactionHistory history; // collection of Transactions

// applys payment to account, returns current balance
public Money applyPayment(Payment payment) {
payment.execute(); // payment posting rules encapsulated, they update the accounts fields and adds to the trans history
return principle.plus(interest);
}

// other operations might include
public Payoff quotePayoff(Date forDate) {}
public Money withdraw(Money requestAmount) {}
public Money deposit(Deposit amount) {}

}

Accounting systems must also support double entry accounting in the form of debits and credits to the general ledger in addition to maintaining balances, applying payments, etc. That's your 'on the record' books of things that gets audited by Auditors in suits. That can be saved for another thread!

-ryan

P. S. Martin Fowler has written extensively on principles of accounting systems and his work has guided me throughout this project. Check out his web site (www.martinfowler.com) for some great references. He proposes an Event based system where Events create one or more Transactions that are related. This model has been effective for us.

rajwant

Posts: 1
Nickname: rajwant
Registered: Aug, 2005

Re: OOP Case Study: The Bank Account Class Posted: Aug 21, 2005 12:50 AM
Reply to this message Reply
I AM NEW IN OOP SO I NEED THE BESIC STRUCTURE HOW THIS IS GOING HERE HOW YOUR CREATING IT AND WHAT ARE THE POINT THAT ONE MUST KEEP IN MIND.
HOPE YOU WILL REPLY SOON

Flat View: This topic has 24 replies on 2 pages [ « | 1  2 ]
Topic: The Harry Potter Theory of Programming Language Design Previous Topic   Next Topic Topic: The Static Function Pointer Table Polymorphism Pattern


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us