Money Bag
O padrão Money Bag (Bolsa de dinheiro) é uma extensão do padrão Money (Dinheiro). O padrão Money é principalmente útil quando trabalhamos com uma única moeda ou multiplas moedas mas elas não podem interagir directamente. Por exemplo, não podemos somar euros com dollars. Contudo em certas circunstâncias é mais simples permitir que haja essa soma porque o resultado final será convertido para uma outra moeda.
O problema
A aplicação trabalha intensamente com valores monetários e é necessário operar sobre valores expressos em moedas diferentes. Usar o padrão Money ajuda, mas obriga a converter tudo para uma certa moeda base antes de proseguir para que os valores sejam coerentes. Se for somado um valor em euro a um valor em dolar e depois subtraido o fator de conversão afeta o resultado final quando na realidade o valor de euro subtraido seria subtraido do valor em euro presente no calculo.
A solução
A solução passa por usar um objeto do tipo Money que possa comportar vários valores em moedas diferentes. Para usar Money Bag é necessário que se use o padrão Money para começar já que todos Money Bag é também um Money.
Como funciona
Criamos uma classe do tipo MoneyBag e fazemos uma implementação equivalente à de Money. A diferença é que nas operações aritméticas deixaremos que a operação de soma e subtração aconteça mesmo quandos os objetos não têm a mesma moeda.
Teremos duas classes: Money que guarda apenas um valor e uma moeda e MoneyBag que guarda vários valores e várias moedas.
Implementação
A impletação é relativamente simples. Fazemos MoneyBag herdar Money e alteramos as operações aritméticas de soma e subtração. Teremos que adicionar um método simplify() para que possamos reduzir um MoneyBag a um Money quando isso for possivel (i.e. quando MoneyBag contiver o valor de apenas uma moeda).
|
|
Código 1: |
|
|
Código 2: |
Esta é uma das muitas implementações possiveis. O ponto importante é que MoneyBar contenha um conjunto de pares moeda-valor. Poderiamos ter usado a propria classe Money para manter esses valores mas optei por usar um mapa de moeda e inteiros.(Porquê inteiros ?)
Conversões
Se estamos trabalhando com várias moedas provávelmente estamos trabalhando também com conversões. Se existir um serviço de conversão disponivel podemos implementar um método simplify() que força que as conversões aconteçam e seja retornado um único valor numa única moeda.
|
|
Código 3: |
Padrões relacionados
Em termos práticos fazer MoneyBag herdar directamente de Money pode ser um problema. Por exemplo, o objeto ConvertionService recebe como argumento um Money mas é esperado que seja um valor uma única moeda. Neste caso é previdente usar o padrão Composite (pelo menos a ideia por detrás do padrão Composite) Desta forma podemos modelar uma interface comum aos dois tipos de objeto e construir implementações independentes. A interface é necessária para o retorno de plus e outros métodos aritméticos.
|
|
Código 4: |
No segundo método simplify() o retorno é concerteza de um só tipo de moeda. Por isso o retorno é garantidamente do tipo Money. Algumas operações de Money como distribute() podem ser mais complicadas de implementar para MoneyBag. Como temos classes separadas para Money e MoneyBag isso não é um problema.
Licença
Sérgio Taborda Este trabalho é licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-Não a obras derivadas 3.0 Genérica . |