Money is a complicated topic, especially if you're dealing with multiple currencies.
for some ideas on making a MoneyObject
. Also see his Money
pattern available at http://www.martinfowler.com/eaaCatalog/money.html
also seen in JavaUnit
"sample application" code.
Memory management issues of ValueObject
s discussed in "Do ValueObjectsRequireGarbageCollection
would have an "Amount" and a "Currency" as attributes.
The "Amount" should be an "assumed decimal" integer, to avoid rounding issues.
(Or, one may still store the value in a floating point variable, but limit usage to integer values. A double can often store more digits than a long.)
Or store it as a number with integer part, numerator and denominator all defined as integers. Then it is up to BusinessObjects or views to deal with the RoundingIssue?s on presentation of the data.
The "Currency" could be a Singleton (SingletonPattern
), and may hold the number of digits (positive or negative) to assume.
Then there's the issue of currency conversion...
There's a lot to be said for accumulating multiple currency amounts in a MoneyBag
, and doing the currency conversion "at the end."
That is, if you can, convert the totals, not the individual detail line amounts.
Widely used exchange rates are really only good for six significant digits at best.
Reality is more like three or four.
So if you're converting a million dollars, it's hard to get really worked up about pennies. ...or dollars, for that matter.
contains a post by KentBeck
, the gist of which is "Why I write a new MoneyObject
for each client". [http://groups.yahoo.com/group/extremeprogramming/message/3304
Java SDK 1.4 introduces a Currency object which can be handy in some cases. Javadoc for it can be found at http://java.sun.com/j2se/1.4/docs/api/index.html
Most money objects are ill conceived. For example, all of large integer, rational number and floating point representations are useful within the same abstraction. Money objects should not round or truncate on their own in any calculation. Rather, rounding is associated with transactions and should be performed in this context. Mixed currency calculations have another set of representational and boundary condition issues which were explored with my work on WyCash
and reported by Kent. -- WardCunningham
You seem to be saying that to do it "right" requires a fairly complex framework that is beyond a single class.
But not all customers really care all that much.
I'm having a hard time getting my business users to care what date is used to exchange the currency.
We're trying to match the currency conversions done by our customers, without knowing the date or exchange rate they used.
We're lucky to get two digits of precision in such a situation.
See also: FloatingPointCurrency