Tenho uma aplicação que estou fazendo code refactoring, e gostaria de fazer algo “diferente”.
Vejam a situação:
Tenho um cadastro de contrato. Neste contrato, há n cláusulas que cada cliente pode colocar. Por exemplo: Dia do pagamento: xx/xx/xxxx, Comissão: xx%, multa: y%/dia, etc.
Eu gostaria de utilizar esses campos para um determinado cálculo. Por exemplo, se o cliente pagou em atraso, quero pegar a multa e fazer o cálculo, e no final do mês recuperar a porcentagem de comissão e calcular com os valores recebidos.
Sendo que, cada cliente tem uma lista de parâmetros diferente.
Alguém já deve ter passado por isso… poderia deixar alguma dica…
Pelo que imagino, cada um dos tipos de contrato tem um tipo diferente de cálculo, de acordo com os parâmetros entrados, certo?
E eles não são uma mera combinação linear dos valores (ou seja, 0.25 x + 0.36 y + 0.27 z). Senão, bastaria fazer uma fórmula e entrar com 0 (ou null) para os parâmetros omitidos.
Talvez seja melhor você criar uma classe CalculoContrato, que tenha diversas subclasses, uma para cada tipo de cálculo, uma factory dessas subclasses, e todas elas devem implementar o método “calcular”. Talvez haja métodos “parcelasContrato” e outras coisas mais. Talvez você possa usar o pattern “Builder” se for o caso.
veja bem, talvez não tenha me explicado corretamente.
Eu tenho uma classe contrato, e em associação com esta classe, uma classe regras do contrato. Em regras, tenho atributos do tipo (os atributos são uma lista de n regras): o usuário escolhe qual regra deseja colocar no contrato. Ate o momento, eu não sei qual regra ou se determinada regra pertencera ao contrato.
Os meus atributos podem ser:
comissão;
multa;
valor;
-data pagamento;
… e qualquer outro atributo que o usuário queira criar como regra.
Para mapear estes atributos, eh bem tranquilo pois eles podem ser do tipo: valor, data, texto, booleano (sim/não).
Mas a questão eh, como utilizar a regra correta por exemplo, para calcular a multa, imaginando que eu tenho uma tabela com essas regras inseridas.
Acho que não é uma arquitetura complicada e sim modelagem errada.
Esses atributos na tabela de regras que você colocou poderiam ser campos da tabela Contrato. Sim, fixos.
Dia do pagamento: xx/xx/xxxx,
Comissão: xx%,
multa: y%/dia.
São claramente atributos de 1 contrato.
Agora se quiser ter a tabela das cláusulas, poderia ter sim, mas não impactante para cálculos.
pois então, eu sei que esses atributos fazem parte do contrato, mas eu gostaria de dar ao usuário uma certa liberdade para cadastrar seus atributos. Veja bem, aqui podemos colocar a multa como um valor específico - uma porcentagem. Mas em certos casos, vou utilizar o IGPM à multa. E aí?
A ideia é deixar esses atributos em aberto, isto é, para que o usuário faça a vinculação daquilo que deseja para o cálculo.
Entendi.
Realmente vai ser difícil ter algo genérico para resolver.
Então acho que você não tem como fugir de definir todas as possibilidades de cálculos em algum lugar. Isso vai gerar um monte de “ifs”, um para cada cálculo em particular.
Imagino algo como:
Contrato --> RegraContrato <-- Regra
Em Regra você terá todas as possibilidades que você imagina. É nesta tabelinha que você deve saber como calcular.
Em RegraContrato o usuário vai vincular as regras que precisa, daí você vai saber como calcular, já que sabe de antemão qual é a regra que foi vinculada.
Acho que sua lista de regras deveria ter além do tipo do valor, um identificador do tipo da regra (Multa, valor, comissão).
Aí você poderia fazer uma classe especializada em calcular cada tipo de regra.
Sobre patterns acho que dá pra pensar em algo com Visitor ou Chain.
Aí você consegue montar dinamicamente uma lista com o quê precisa ser calculado, mesmo que o contrato tenha outras regras.
Mas ainda tem alguns pontos obscuros. Vejam bem, tenho a regra juros, e é associado a um contrato. Isso sem problemas. Se olhar bem, eu não sei como calcular o juros, portanto, o usuário deverá inserir uma fórmula para cálculo desse juros, e a partir da regra Juros terei que associar um cálculo. Em consequência disso, terei outra tabela para armazenar os diversos cálculos que tenho para cada regra.
Bom, mas imagine se o contrato extrapolar a data normal e terei que cobrar juros. Como falar ao sistema que tenho que executar aquele regra com aquele cálculo? Eu teria que ter outras regras associadas, como por exemplo, se atingir a data limite, tenho que executar aquele regra de Juros para determinados atributos.
A medida que tento abstrair as coisas, mais regras tenho que inserir.