Trabalhar com valores monetários em Java

Amigos, apesar de saber que esse já é um tema bastante discutido em outros tópicos aqui no GUJ e que muitos irão me dizer: “olha esse ou aquele post, se trata do mesmo assunto” vou levantar novamente a questão porque em nenhum dos tópicos que li encontrei uma solução adequada e comumente aceita.
A dúvida é: qual tipo vocês costumam dar aos atributos de valores monetários (dinheiro) nos seus sistemas ? Double ? BigDecimal ? Uma implementação do pattern Money ? E, se possível, por quê utiliza este tipo ?

Ah, e se alguém puder falar um pouco sobre a JSR 354 (Money and Currency API) também seria bom.

Desde já, agradeço.

Cara, é inevitável dizer pra vc não olhar em outro post…

Esse post resolveu meu problema, e uso até hoje

vlw

[quote=Henrique Moraes]Cara, é inevitável dizer pra vc não olhar em outro post…

Esse post resolveu meu problema, e uso até hoje

vlw[/quote]

Cara, acho que me expressei mal. Não me refiro a tipos para campos de GUI [swing], e sim, tipos para atributos de JavaBeans. Qual o tipo mais indicado para atributos que receberão valores monetários: Double, BigDecimal ou uma implementação do pattern Money? Não sei se você sabe, mas existem alguns problemas com casas decimais quando se armazena valores monetários em campos do tipo Double e, houvi falar, que estes problemas ocorrem até mesmo em campos do tipo BigDecimal.

Mesmo assim, obrigado.

Continuo na dúvida.

[quote=joparibeiro][quote=Henrique Moraes]Cara, é inevitável dizer pra vc não olhar em outro post…

Esse post resolveu meu problema, e uso até hoje

vlw[/quote]

Cara, acho que me expressei mal. Não me refiro a tipos para campos de GUI [swing], e sim, tipos para atributos de JavaBeans. Qual o tipo mais indicado para atributos que receberão valores monetários: Double, BigDecimal ou uma implementação do pattern Money? Não sei se você sabe, mas existem alguns problemas com casas decimais quando se armazena valores monetários em campos do tipo Double e, houvi falar, que estes problemas ocorrem até mesmo em campos do tipo BigDecimal.

Mesmo assim, obrigado.

Continuo na dúvida.[/quote]

Cara… acho que depende muito da situação…
se for levar ao pé da letra o correto mesmo seria usar o pattern money, afinal fica muito mais facil para trabalhar conversões, etc…
mas no geral se for um sistema que só precisa representar valores em real (R$), não vejo problema de usar o BigDecimal…

e ah… isso pq dependendo da implementação do pattern pode deixar o sistema “um pouco mais pesado”…

E o problema geralmente não costuma ser o armazenamento do valor, mas sim na hora de realização de calculos…

http://martinfowler.com/eaaCatalog/money.html

1 curtida

Trabalho há cinco anos com sistemas financeiros.
Utilizamos a classe BigDecimal e nunca tivemos grandes dificuldades com ela, ao contrário de Double, que sempre acaba num relatório com valor “-0,00”.
Na minha opinião, o maior cuidado necessário com o BigDecimal é tratar corretamente as casas decimais.
Por exemplo, no momento de exibir um valor numérico, nós sempre definimos o número de casas decimais e o método de arredondamento deve estar bem definido.

[quote=utluiz]Trabalho há cinco anos com sistemas financeiros.
Utilizamos a classe BigDecimal e nunca tivemos grandes dificuldades com ela, ao contrário de Double, que sempre acaba num relatório com valor “-0,00”.
Na minha opinião, o maior cuidado necessário com o BigDecimal é tratar corretamente as casas decimais.
Por exemplo, no momento de exibir um valor numérico, nós sempre definimos o número de casas decimais e o método de arredondamento deve estar bem definido.
[/quote]

Foi como falei, se não precisa tratar moedas diferentes o BigDecimal atende.
Mas imagina o caso de uma loja virtual que precisa apresentar preços em reais e dollar… e aplicar regras diferentes dependendo da moeda… nesse caso aplicar o pattern money acaba ajudando… se não acaba ficando espalhado pelo código um monte de conversão e regra e um monte de if tipo de moeda… muito comum isso em sites feitos em php (nada contra php, que também pode aplicar money, mas geralmente a galera faz tudo por script)

Lendo textos como http://sergiotaborda.wordpress.com/desenvolvimento-de-software/java/faq/numeros/ e http://sergiotaborda.wordpress.com/desenvolvimento-de-software/java/patterns/money/ resolvi optar pela implementação do pattern Money. Seguirei padrões para não ter problemas no futuro e, além disso, pelo que li, a JSR 354 também seguirá estes padrões.

Obrigado pelas sugestões.

Entendi. Realmente eu não quis falar do BigDecimal como solução para tratar moedas diferentes, mas apenas do caso de ter problemas de arredondamento e “zeros negativos”.

Aqui na empresa nós não usamos o pattern money porque muitos sistemas foram migrados de legados que não eram OO.
Também usamos muitas procedures por questões de performance, então não vejo muito como aplicar esse pattern, que faz mais sentido quando se deseja manipular valores em código OO.

Apesar disso, não sentimos nenhuma necessidade de usar esse pattern porque a experiência nos ensinou algumas técnicas que deixaram o tratamento de valores em moedas diferentes relativamente fácil.
A primeira coisa é ter uma moeda base, que no nosso caso é o Real. Então temos uma tabela de índices diários das moedas com que trabalhamos. Esta tabela não é alimentada somente com a cotação do dia, mas contém um campo com um fator multiplicador, que é calculado de acordo com a regra da moeda ou índice. Basta multiplicar o valor por um fator, independente da moeda, e você terá o valor convertido na respectiva moeda.
Dessa forma, a conversão é sempre direta. Somente é necessário aplicar a regra do índice no momento do cadastramento para gerar esse fator e todo o resto do código fica simples e direto.