Vamos começar a usar BigDecimal aqui na empresa e reparei que ele não possui métodos para comparação. Podemos sua implementação do compareTo(), mas queríamos algo mais simples, como um método “BigDecimal.greaterThen(BigDecimal)” que retorne um boolean. Para isso, pensamos em criar uma especialização de BigDecimal, algo como:
public classe MyBigDecimal extends BigDecimal {
Quais seriam as desvantagens dessa solução? Estou pensando em fazer um teste no Hibernate, não sei se ele conseguiria transformar uma informação armazenada no banco de dados com o tipo de dado DECIMAL (MySQL) em um objeto da classe MyBigDecimal.
Essa é a mágica da herança, se a uma classe não satisfaz suas necessidades por estar “incompleta”, criar uma classe persnalizada à partir dela é sem dúvida uma ótima saída. Suponho que BigDecimal.greaterThen(BigDecimal) não é a única coisa que vc pretende implementar, então vai fundo!
Quanto ao hibernate, creio que isso tb não vai gerar problemas, pois se vc implementar uma classe derivada de BigDecimal, sua classe tb será um BigDecimal!
Acho que não vale a pena; é melhor ter uma classe Calc que use BigDecimal para facilitar as contas.
Embora BigDecimal não seja "final" acho que ela deveria ser considerada como "final", como a classe String.
Um exemplo (é claro que eu não tenho aqui uma classe "Calc" mas é um exemplo para você ter uma idéia do que parece melhor para você):
Calc cl = new Calc();
cl.setPrecision (4); // fazer todos os cálculos com no máximo 4 casas depois da vírgula - você está trabalhando com divisão, não?
BigDecimal result = cl.calc ("a + (2.3 * b / c) - 1.24", new BigDecimal ("23"), new BigDecimal ("45.67"), new BigDecimal (66.78));
BigDecimal result2 = new BigDecimal ("345").multiply (new BigDecimal ("23.45"));
if (cl.comp ("a/4.5 + 7 < b * 1.3", result, result2)) {
...
}
onde “a” é o primeiro parâmetro, “b” o segundo, “c” o terceiro etc, e “calc” uma função que calculasse a expressão e retornasse um BigDecimal, e “comp” uma função que calculasse a expressão e retornasse um boolean.
Outra forma (talvez seja um pouco mais flexível):
Calc cl = new Calc();
BigDecimal preco, custo = new BigDecimal ("23.45"), lucro = new BigDecimal ("10.0"), aliquota = new BigDecimal ("0.38");
cl.setPrecision (4);
// Note que isto não pode ser feito por reflection porque os nomes de variáveis locais não são disponíveis via reflection. Sorry...
cl.set ("custo", custo);
cl.set ("aliquota", aliquota);
cl.set ("lucro", lucro);
preco = cl.calc ("custo * (1 + aliquota / 100) + lucro");
Note que se houvesse overload de operadores apenas para o BigDecimal seria legal - evitaria essa gambiarra de criar uma classe para fazer avaliação de expressões.
Cuidado com a língua “ingresa” - se você vai realmente criar um MyBigDecimal pelo menos batize a função de “greaterTh[size=18]a[/size]n” (maior que), não “greaterTh[size=18]e[/size]n” (maior então?)
Eu pessoalmente trabalho com BigDecimal a algum tempo, e embora estes métodos façam alguma falta, eu me viro com o compareTo. É melhor você criar um método estático para fazer a comparação do que criar uma subclasse de BigDecimal.
Criar subclasses neste caso é uma má idéia porque os seus métodos novos não serão aplicáveis a qualquer BigDecimal, apenas aos seus! Assim, se alguma API te retornar um BigDecimal (JDBC por exemplo), ele não vai te servir porque você não está trabalhando com BigDecimal, e sim com uma subclasse de BigDecimal, e o BigDecimal obtido não é da sua subclasse.
Embora muitos textos de introdução a OO demonstrem o poder de alterar/consertar uma classe criando-se subclasses, na minha opinião, isso é uma péssima idéia. Aliás, isso inclusive é um (anti)padrão POG muito bem conhecido chamado BaseBean.
Eu sempre recomendo criar uma classe “Currency”(Moeda) ou algo assim para esses casos.Fora o risco de comportamentos “bizarros” que podem ocorrer, como umas Exceptions enjoadas(hoje isso melhorou…)