 |
The Money class is supposed to work entirely with decimal (not floating point) arithmetic, to avoid rounding problems - as described in places like Martin Fowler's Patterns of Enterprise Application Architecture.
The reality is short of that ideal:
- Many callers to new Money(String) get their string from a call to Double.toString(doubleValue)
- There are many callers to Money#amountAsDouble, a method which should not exist.
While we're on the subject of Money, some methods don't make sense (Money#multiply(Money), for example - it should just be Money#multiply(Double) - where the second argument maybe could be changed to BigDecimal or int or something, but not Money), which is making the callers do strange things about what is stored in a Money and what is not.
The TimeAndMoney library is worth considering, if we're refactoring Money anyway.
Another issue related to the Money class and monetary storage in general is the way that Money gets persisted to the database is a pair of fields (amount and currency). This is awkward and probably would be more natural to have the currency selected at a coarser level (per-account or per-branch, say). This will all make more sense once we do Multicurrency for real - right now all those currency fields don't really do anything.
There are some links at InterestingTechQuestions to various currency rounding articles (a somewhat random collection, and probably worth moving the relevant bits to this page, but someplace to start).
|