Tive uma ideia de implementação utilizando o próprio Enum do java. Não sei sei tem alguma limitação, mas pelo menos para a regra de negócio em questão parece funcionar bem. O que acham?
package state;
import java.math.BigDecimal;
public enum Situacao {
APROVADO{
@Override
public void finalizar(Orcamento orcamento) throws Exception {
orcamento.setSitucao(Situacao.FINALIZADO);
}
@Override
public BigDecimal calcularDescontoExtra(Orcamento orcamento) {
return orcamento.valor.multiply(new BigDecimal("0.02"));
}
},
REPROVADO{
@Override
public void finalizar(Orcamento orcamento) throws Exception {
orcamento.setSitucao(Situacao.FINALIZADO);
}
},
EM_ANALISE{
@Override
public void aprovar(Orcamento orcamento) throws Exception {
orcamento.setSitucao(Situacao.APROVADO);
}
@Override
public void reprovar(Orcamento orcamento) throws Exception {
orcamento.setSitucao(Situacao.REPROVADO);
}
@Override
public BigDecimal calcularDescontoExtra(Orcamento orcamento){
return orcamento.valor.multiply(new BigDecimal("0.05"));
}
},
FINALIZADO;
public void aprovar(Orcamento orcamento) throws Exception {
throw new Exception("Não pode ser aprovado");
}
public void reprovar(Orcamento orcamento) throws Exception {
throw new Exception("Não pode ser aprovado");
}
public void finalizar(Orcamento orcamento) throws Exception {
throw new Exception("Não pode ser aprovado");
}
public BigDecimal calcularDescontoExtra(Orcamento orcamento) {
return BigDecimal.ZERO;
}
}