Interface de Desconto
public interface IDesconto
{
IDesconto Proximo { get; set; }
public double CalculaDesconto(Orcamento orcamento);
}
Template com comportamento para o Desconto.
- Recebe um desconto no construtor para ser o próximo (se necessário).
- comportamento para verificar condição válida de aplicação do desconto
- comportamento para calcular o valor do desconto.
public abstract class TemplateDesconto : IDesconto
{
public IDesconto? Proximo { get; set; }
public TemplateDesconto (IDesconto? proximo = null)
{
this.Proximo = proximo;
}
public double CalculaDesconto(Orcamento orcamento)
{
if (CondicaoValidaParaDesconto(orcamento))
{
return GeraValorDesconto(orcamento);
}
if (Proximo != null)
{
return Proximo.CalculaDesconto(orcamento);
}
return 0;
}
protected abstract double GeraValorDesconto(Orcamento orcamento);
protected abstract bool CondicaoValidaParaDesconto(Orcamento orcamento);
}
Exemplo de desconto por valor:
- Recebe o valor que você quer comparar
- Porcentagem para calculo
- se necessário um IDesconto para ser o próximo.
- ValorMaximo (caso exista um Próximo e seja um desconto por valor também)
public class DescontoPorValor : TemplateDesconto
{
double Porcentagem { get; set; }
double Valor { get; set; }
double ValorMax { get; set; }
public DescontoPorValor(double valor, double porcentagem, IDesconto proximo = null, double valorMax = 0)
: base(proximo)
{
this.Valor = valor;
this.Porcentagem = porcentagem;
this.ValorMax = valorMax;
}
protected override bool CondicaoValidaParaDesconto(Orcamento orcamento)
{
if (ValorMax != 0)
{
return orcamento.Valor > this.Valor && orcamento.Valor <= this.ValorMax;
}
return orcamento.Valor > this.Valor;
}
protected override double GeraValorDesconto(Orcamento orcamento)
{
return orcamento.Valor * (this.Porcentagem / 100);
}
}
Calculador de descontos: Faz a instância de 3 descontos por valor, passando como parâmetro o valor mínimo, a porcentagem de desconto, o próximo desconto e o valor máximo.
Nesse exemplo se o valor estiver entre 500 e 1000 o desconto será de 10%....
Entre 1000 e 2000 - Será de 20%...
Acima de 2000 - 25%..
public class CalculadorDescontosTm
{
public double CalculaDesconto(Orcamento orcamento)
{
IDesconto desconto3 = new DescontoPorValor(2000, 25);
IDesconto desconto2 = new DescontoPorValor(1000, 20, desconto3, 2000);
IDesconto desconto1 = new DescontoPorValor(500, 10, desconto2, 1000);
return desconto1.CalculaDesconto(orcamento);
}
}
Program.CS para execução:
Console.WriteLine("Calculador de descontos");
Console.WriteLine("Gerando um orçamento de teste");
Orcamento orcamento = new Orcamento();
orcamento.AdicionaItem(new Item("RTX 2060 Super", 1000));
orcamento.AdicionaItem(new Item("Placa mãe", 600));
orcamento.AdicionaItem(new Item("Kit Mouse e Teclado", 200));
Console.WriteLine($"Orcamento gerado com valor de {orcamento.Valor} com total de {orcamento.QuantidadeItens()} itens.");
Console.WriteLine("Aplicando descontos....");
CalculadorDescontosTm calculador = new CalculadorDescontosTm();
Console.WriteLine($"Desconto gerado: {calculador.CalculaDesconto(orcamento)}");
Dessa forma podemos implementar outros tipos de descontos, herdando do TemplateDesconto e implementando apenas os métodos CondicaoValidaParaDesconto e GeraValorDesconto;
public class DescontoPorItens : TemplateDesconto
{
protected override bool CondicaoValidaParaDesconto(Orcamento orcamento)
{
return orcamento.QuantidadeItens() > 10;
}
protected override double GeraValorDesconto(Orcamento orcamento)
{
return orcamento.Valor * 0.05;
}
}