Question

After reading some of "Clean Architecture" I got the idea that perhaps I should reconsider the way I have architected a chart of accounts/accounts object in an accounting program.

I have accounts which live in a tree structure like this:

Budget account (root) 
   Sections (0..n)
     Accounts (0..n)
       Subaccounts (0.n)
          LineItems(0..n)`

Only line items have an actual concrete 'total' value, which is entered by a user and stored as a number field. Each level of the hierarchy derives the total from the sum of its children's total, so the Budget Account total is ultimately equal to the sum of all the line items.

My question is this -- Should the 'total' property above 'lineitem' of each account be implemented as a function equal to something like

get total() :number {
  return (sumOf(children.total())
} 

, or should it be designed as a number field on each account which is updated in response to user lineitem changes by responding to an observable which announces changes in the values of any of accounts children?

In the former case, accuracy and maintainability, simplicity, concurrence are all probably increased if there is only one set of actual data to be maintained at the line item level, but it just seems like a heck of a lot of processing that has to happen each time a page with accounts has to show its total. For example if a page header {{budgetAccount.total}} that in turn would provke a process where every single account is recursed through a loop to calculate the total -- on every page referesh! And if you print the entire chart of accounts, the same numbers are added over and over and over each time an account.total is requested. However, with the speed of and capacity of todays machines and browser and I don't have akeen sense if the burden of all this processing is actually meaningful or not and worth persisting some of these imemdiate totals within the accoutn object, so they don't need recalculation everytime some uses the getter.

For context, might be 20K-30K lineitems in my actual budget, split over maybe 1,000 accounts at various levels. But of course, an exceptionally large budget may come along with as many as 100,000 or 500,000 line items. In my application, the entire budget structure is kept in memory once retrieved from the back end..

What the factors that should be considered in this decision?

Was it helpful?

Solution

Auditors

Love them or hate them, they will get there hands into any system of account.

Presuming that this is such an accounting system, which is easier to explain?

  1. Here is the exact value as displayed on the customers invoice. It may be incorrect, but that was what was displayed, and as such our contractual obligation.

  2. Here is a bunch of code, and this is how you understand what was done, and ignore that commit its not on the main line, and yes if the customer were to come back and look at their invoice today, it would not match the invoice they were given then.

Personally auditors do not take well to having to learn a programming language. Your auditors may be different.

Trade Off

Which is more important to you - Clock cycles or Memory?

If Clock cycles are costly, then a single computation and sacrificing some memory works.

If Memory is more costly, then on demand calculations is the cost of having that space available.

If they are mixed, perhaps a memoised map? If the value exists return it, otherwise calculate it and insert it before returning it. Not enough space? pick one of the older results and replace it/just empty the entire cache.

Assumptions

What precisely do you mean by todays computers?

  • A Cray? it might be overkill.
  • My watch? You are surely joking.

Pick your actual baseline, and test using a machine built to that baseline. Collect your results and experiment on different ways until you come up with something working/or give up and upgrade the baseline.

Also remember that the baseline machine is probably running other software, like anti-virus, web browser, a back ground file cleaner, etc.. Not all of those resources are uniquely available to your program.

Licensed under: CC-BY-SA with attribution
scroll top