Quando se acha que está entendendo as coisas... A resposta deste exercício foi exatamente aquilo que eu esperava que não fosse ser: Um If testando uma flag!
Seguindo a proposta do Design Pattern, o que eu fiz foi criar dois novos estados intermediários, um "Em Aprovação com Desconto Aplicado", e outro "Aprovado com Desconto Aplicado". Essas classes seriam idênticas a Em Aprovação e Aprovado, respectivamente, exceto pelo método AplicaDesconto, que no caso dos "Já Aplicados" retornaria apenas a exceção...
Dito isso, será que esta minha resposta é válida? Ou ela cria complicações desnecessárias? Qual seria o ideal? Testar uma flag, como no exercício?
Sinto estar tendo dificuldades em saber quando não usar um Design Pattern... :-p
Segue o código do estado "Aprovado" e do estado intermediário "Aprovado com Desconto Aplicado", a título de exemplo:
using System;
namespace DesignPatterns
{
public class Aprovado : EstadosOrcamento
{
public void AplicarDesconto(Orcamento orc)
{
orc.Valor = orc.Valor - (orc.Valor * 0.02);
orc.Estado = new AprovadoDescontoAplicado();
}
public void Aprovar(Orcamento orc)
{
throw new Exception("Este orçamento já estava aprovado.");
}
public void Finalizar(Orcamento orc)
{
orc.Estado = new Finalizado();
}
public void Reprovar(Orcamento orc)
{
throw new Exception("Não é possível reprovar um orçamento já aprovado.");
}
}
}
using System;
namespace DesignPatterns
{
class AprovadoDescontoAplicado : EstadosOrcamento
{
public void AplicarDesconto(Orcamento orc)
{
throw new Exception("O desconto de 2% é único, não cumulativo. Só pode ser aplicado uma vez.");
}
public void Aprovar(Orcamento orc)
{
throw new Exception("Este orçamento já estava aprovado.");
}
public void Finalizar(Orcamento orc)
{
orc.Estado = new Finalizado();
}
public void Reprovar(Orcamento orc)
{
throw new Exception("Não é possível reprovar um orçamento já aprovado.");
}
}
}