Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Dúvida] Solução Diferente da Proposta

Olá! Resolvi o exercício proposto de uma maneira diferente, Funcionou, Porém não sei se é uma boa prática no dia a dia realizar este procedimento.

Classe "Em Aprovação"

public class EmAprovacao : EstadoDeUmOrcamento
{
    public void AplicaDescontoExtra(Orcamento orcamento)
    {
        orcamento.Valor -= orcamento.Valor * 0.05;
        orcamento.EstadoAtual = new EmAprovacaoComDescontoDado();
    }

    public void Aprova(Orcamento orcamento)
    {
        orcamento.EstadoAtual = new Aprovado();
    }

    public void Finaliza(Orcamento orcamento)
    {
        throw new Exception("Orçamento em Aprovação não pode ser Finalizado diretamente!");
    }

    public void Reprova(Orcamento orcamento)
    {
        orcamento.EstadoAtual = new Reprovado();
    }
}

Classe "Em aprovação com desconto dado"

public class EmAprovacaoComDescontoDado : EmAprovacao, EstadoDeUmOrcamento
{
    public void AplicaDescontoExtra(Orcamento orcamento)
    {
        throw new Exception("Desconto Já Realizado nessa etapa");
    }

    public void Aprova(Orcamento orcamento)
    {
        base.Aprova(orcamento);
    }

    public void Finaliza(Orcamento orcamento)
    {
        base.Finaliza(orcamento);
    }

    public void Reprova(Orcamento orcamento)
    {
        base.Reprova(orcamento);
    }
}

Desta Maneira eu consegui eliminar a condicional dentro do método AplicaDescontoExtra e lançar a Exceção como proposto. A Classe EmAprovacaoComDesconto estende de EmAprovacao para que em uma manutenção futura eu apenas altere as funções na classe Pai, também implementei a Interface EstadoDeUmOrcamento para poder linkar a referência na propriedade EstadoAtual da classe Orcamento. (Não entendi porque não consegui fazer esse "link" apenas herdando de EmAprovacao", já que ela implementa essa interface)

Com esse mesmo pensamento repliquei a solução para as classes Aprovado e AprovadoComDescontoDado.

Como disse anteriormente, não sei se essa foi uma boa prática, se houver alguma sugestão poderiam me ajudar a melhorar o código?

Agradeço desde já!

3 respostas
solução!

Olá, Marcelo!Bom dia, tudo bem?

Parabéns por resolver o exercício proposto de uma maneira diferente! É sempre bom explorar diferentes abordagens e soluções.

Sua solução de criar a classe "EmAprovacaoComDescontoDado" que estende a classe "EmAprovacao" e implementa a interface "EstadoDeUmOrcamento" é uma forma interessante de reutilizar código e facilitar futuras manutenções. Ao fazer isso, você permite que as alterações sejam feitas apenas na classe pai, como você mencionou.

Quanto à sua dúvida sobre por que não conseguiu fazer o "link" apenas herdando de "EmAprovacao", é provável que isso esteja relacionado à forma como a classe "Orcamento" está implementada. Talvez a propriedade "EstadoAtual" esteja declarada como do tipo "EstadoDeUmOrcamento" e, por isso, seja necessário implementar a interface diretamente na classe "EmAprovacaoComDescontoDado". Sem mais informações sobre a implementação da classe "Orcamento", é difícil dar uma resposta mais precisa.

Em relação a sugestões para melhorar o código, acredito que sua solução está adequada e atende ao propósito do exercício. No entanto, sempre é possível buscar por outras abordagens e refatorar o código para deixá-lo mais legível e eficiente. Por exemplo, você poderia considerar o uso de um padrão de projeto, como o State, para tratar os diferentes estados do "Orcamento". Esse padrão pode ajudar a organizar melhor o código e facilitar futuras alterações.

Espero ter ajudado e bons estudos!

Marcelo,

Talvez você ache isto interessante, o princípio da Separação de Conceitos:

Princípio da Separação de Conceitos

.NET - Princípios básicos de um projeto de software

Separe responsabilidades (Separation of Concerns)

https://www.macoratti.net/11/11/net_pbps.htm

[]'s,

Fabio I.

Olá senhores!

Primeiramente obrigado pelas respostas!

André, Realmente a propriedade EstadoAtual na classe orcamento é um EstadoDeUmOrcamento :

public class Orcamento
{
    public EstadoDeUmOrcamento EstadoAtual { get; set; }

    public Orcamento(double valor)
    {
        Valor = valor;
        Itens = new List<Item>();
        EstadoAtual = new EmAprovacao();
    }
    public double Valor { get; set; }
    public List<Item> Itens { get; private set; }

    public void AdicionaItens(Item item)
    {
        Itens.Add(item);
    }

    public void AplicaDescontoExtra()
    {
        EstadoAtual.AplicaDescontoExtra(this);
    }

    public void Aprova()
    {
        EstadoAtual.Aprova(this);
    }
    public void Reprova()
    {
        EstadoAtual.Reprova(this);
    }
    public void Finaliza()
    {
        EstadoAtual.Finaliza(this);
    }
}

Meu pensamento inicial era o seguinte: "Já que EmAprovacao implementa EstadoDeUmOrcamento, se eu estender minha classe EmAprovacaoComDescontoDado ela também seria EstadoDeUmOrcamento". Porém parando para pensar não faz sentido, EmAprovacaoComDescontoDado deve implementar a interface para funcionar corretamente.

Fábio, Artigo interessante, irei estudar profundamente e com calma, Como estamos falando sobre State achei que seria viável criar uma classe para representar o estado EmAprovacao mas com desconto dado, não me atentando a responsabilidade única. Obrigado!