0

Assume we are designing a typical bank account management system. Customers can have one or more accounts. Customers can deposit cash, withdraw cash or transfer money to another account (and, of course, view the balance).

If all accounts are contained in the same bank, one could, for example, design a Customer class and a BankAccount class. The BankAccount class would have getBalance(), deposit(sum), withdraw(sum), and transfer(sum,targetAccount) methods. When transfering money, the "source" balance decreases and the "target" account balance increases.

However, in the real world, you can transfer money to another account in a completely different bank (potentially in a different country). Ignoring issues related to atomicity and so on (for the sake of simplicity), how would you implement this scenario?

One may be tempted to use inheritance: BankAccount is a super-class, with sub-classes OwnBankAccount and OtherBankAccount. OwnBankAccount implements the transfer(sum,targetAccount) method in a "local" naif way, whereas OtherBankAccount implements the transfer(sum,targetAccount) method sending, say, a REST API call to the other bank.

However, I'm not sure this is possible, because the BankAccount would have to implement some kind of switching logic to decide which subclass to call and, as far as I know, a super-class cannot call a sub-class.

So, how should we deal with this kind of requirement?

3
  • "BankAccount would have to implement some kind of switching logic to decide which subclass to call" you mean a virtual function? Commented Jan 28 at 13:50
  • @PhilipKendall this would require an additional class that is neither the superclass nor the subclass, right? Something "external" that explicitly creates objects from OwnBankAccount or OtherBankAccount? I'm confused because, in this scenario, the method that should be overridden requires a source and a destination account, but at most one of them can belong to OtherBankAccount (because otherwise the money transfer wouldn't involve this bank). So I don't think you can simply create an object in the right subclass and call the transfer method. Anyway, feel free to expand that into an answer.
    – A. Darwin
    Commented Jan 28 at 14:02
  • The core issue with this question is that it boils down to "hey let's vet this idea that I have" while at the same time skipping over essential cornerstones of how financial systems are built to work and oversimplifying things to the point of making further discussion on the subject misguided at best and unusable at worst. If you are a learner it's not bad to try and think of how you would model things; but this isn't really the core topic of StackExchange. Instead, I would suggest you build the system and see if it works for you rather than having others vet your ideas for you.
    – Flater
    Commented Jan 29 at 22:42

1 Answer 1

4

Assume we are designing a typical bank account management system.

I would say let's not, because your question reveals that you don't know yet about the simplest accountancy, let alone about inter-bank transfers.

If all accounts are contained in the same bank, one could, for example, design a Customer class and a BankAccount class. The BankAccount class would have getBalance(), deposit(sum), withdraw(sum), and transfer(sum,targetAccount) methods.

No, not very close.

The most basic concepts of bookkeeping are a ledger, a journal, a calendar, an account-list, and debits and credits.

A ledger is a list of accounting entries. A journal links together entries which appear in the ledger and which form a single transaction. A calendar defines the available periods in which a transaction can occur. And the account-list defines the available accounts which a transaction can affect.

Amounts are recorded as either a debit or a credit. Debit and credit are opposites and follow the same arithmetic relationship as positive and negative numbers, but there is no rule about which one is treated as positive and which is treated as negative (often debits and credits are recorded and shown in separate fields, both as positive amounts, or if they are shown as a single net figure then the sign used to represent net debit or net credit is arbitrary and particular to context).

A single transaction always involves at least two entries being made into the ledger, affecting at least two accounts.

A deposit of cash by a client would lead to two entries in a ledger. A "cash on hand" account is debited (which in this context means cash is received), and a client account is credited (which means a debt is owed to that client).

A withdrawal of cash by a client would lead to cash being credited and the client account being debited.

A transfer between two client accounts would lead to the remitter's account being debited and the beneficiary's account being credited.

You'll notice I've fallen back into casually talking about the accounts being debited and credited. What I mean by this is an entry is made in the ledger, stating an amount and referencing an account.

None of the three operations belong to an individual account - which (in essence) is merely a reference number defined in the account-list.

In accountancy done on paper, these operations belong to the accounting clerk. A deposit? The clerk. A withdrawal? The clerk. A transfer? Again, the clerk.

In an application of a computer to accountancy and the conceiving of source code, where it may be regarded as convenient to think of the operations as occurring neither by the clerk using the computer nor by the computer as a whole, the most appropriate place for these operations would probably be the ledger, with a signature such as:

void EnterLedgerLines(lineList)

The difference between a deposit, withdrawal, or transfer, is not in the different operations which they involve - they all involve the same operation of making an accounting entry - but merely in the data which is entered (which accounts are referenced by the entry).

There's an important lesson here also about object-oriented modelling. Many things in the real world don't work the way software developers think they do - especially not software developers who have learned nothing about the professions they're writing software for.

There is a toxic theme in the schooling of many software developers, where they are encouraged to use only their imaginations for modelling, rather than studying and analysing specific professions or gaining real work experience.

How professionals think about things often doesn't involve the same concepts or relationships as object-oriented modellers tend to imagine, or even the same philosophy in which operations belong to particular kinds of "objects".

The only objects that exist in accountancy which actually do anything - which have operations - are the accountants. Everything else is static paperwork.

The accounts are not like little vending machines into which you insert cash into a slot or demand repayment by pressing a button, or where a transfer involves a little conveyor belt between two such vending machines. The accounts are simply reference numbers that help organise the ledger lines together.

5
  • I think I get the spirit but I'm not sure how this could be translated in actual code, at least using an OOP approach. If accounts are simply reference numbers, should we have a BankAccount class with no method, and a Ledger class which adds lines containing a source account, a target account and a sum? If so, would the BankAccount have its own balance or should it be computed every time by looking at the ledger? I know OOP is not the only programming paradigm, but it is one of the most common, so I'm curious as to how one should think about this problem with the proper domain knowledge.
    – A. Darwin
    Commented Jan 28 at 14:30
  • @A.Darwin, in accountancy, nothing concerning amounts is ever done with just a single account. You might have methods on BankAccount, but it wouldn't be anything to do with moving money, because that is always something that is an operation involving multiple accounts, at least two but sometimes three or more. Balances may be stored, but it is very often not stored in the account list, because the list doesn't frequently change but the current balance often does. So you'd have an AccountCurrentBalance record which references the Account, but is distinct from the Account record itself. (1/2)
    – Steve
    Commented Jan 28 at 15:14
  • 2
    Also it's not merely about competing but equally valid "paradigms". It's about a toxic approach to OO modelling itself (an approach seemingly encouraged by educators) in which firstly the modeller knows nothing about the concepts in the application area, surviving on imagination, and then secondly everything is treated like a little machine in a menagerie of such machines, which all interact with one another, whilst being disinclined to accomodate that in the real world there are objects which exist only as places to store information and which have no "behaviours" of their own. (2/2)
    – Steve
    Commented Jan 28 at 15:16
  • To explain further, in accountancy, an individual account is not a place where money is stored, but something that defines a grouping of ledger entries. It is a tenet of accountancy that each ledger entry must be associated with such a defined grouping. (The other important groupings are the "journal" and the "period" btw). Such a grouping has no intrinsic dynamical behaviour of its own, and in a paper accounting system an account corresponds to a line of data, not to a physical item. The physical items (besides the clerks) always correspond to lists (each with multiple entries of data).
    – Steve
    Commented Jan 28 at 15:43
  • 1
    @A.Darwin supporting Steve's point here but boiling it down a slight bit further (which I suspect would help you here): you've not really appreciated the complexity of the system, and are therefore thinking that a much too simple implementation covers all of the requirements. It doesn't. It would be a fruitless endeavor to try and discuss your idea here when it is apparent that the idea was built on a misunderstanding of the requirements and complexities. You need to do more research into the problem domain before considering what kind of solutions you can provide here.
    – Flater
    Commented Jan 29 at 22:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.