public class LimiteDeSaldo { private BigDecimal disponivel; private BigDecimal concedido; private BigDecimal margemDeCredito; public LimiteDeSaldo(BigDecimal disponivel, BigDecimal concedido, BigDecimal margemDeCredito) { this.disponivel = disponivel; this.concedido = concedido; this.margemDeCredito = margemDeCredito.setScale(2, RoundingMode.HALF_DOWN); } public void debita(BigDecimal valorASerDebitado) { if (!possuiDisponivel(valorASerDebitado)) throw new LimiteDeSaldoDisponivelInsuficienteException(disponivel); disponivel = disponivel.subtract(valorASerDebitado); } public void debitaSemConsultaDeLimite(BigDecimal valorASerDebitado) { disponivel = disponivel.subtract(valorASerDebitado); } private boolean possuiDisponivel(BigDecimal valor) { return getDisponivelComMargemDeCredito().compareTo(valor) >= 0; } private BigDecimal getDisponivelComMargemDeCredito() { return calculaDisponivelComMargemDeCredito(); } private BigDecimal calculaDisponivelComMargemDeCredito() { BigDecimal margem = disponivel.multiply(margemDeCredito); return disponivel.add(margem).setScale(2, RoundingMode.UP); } }