Melhore seu código C#— parte 2 — tem “if” demais no código !

Marcio Nizzola
3 min readAug 28, 2024

--

Melhore seu código c# — parte II — tem “if” demais no código !

Continuando a postagem anterior onde falei sobre qualidade de código (vide link), agora iremos falar de outros pontos

Estruturas de Decisão Encadeadas

Outro desafio comum são as estruturas de decisão “if” encadeadas. Quando temos vários “if”s dentro de “if”s, o código se torna confuso e difícil de seguir, dificultando a testabilidade e a manutenção. Vamos ver um exemplo de como isso pode ocorrer em C#:

Exemplos de if´s encadeados:

public class CalculadoraDesconto
{
public decimal CalcularDesconto(string tipoCliente, decimal valorCompra)
{
if (tipoCliente == "Regular")
{
if (valorCompra > 1000)
{
return valorCompra * 0.10m;
}
else
{
return valorCompra * 0.05m;
}
}
else if (tipoCliente == "VIP")
{
if (valorCompra > 1000)
{
return valorCompra * 0.20m;
}
else
{
return valorCompra * 0.15m;
}
}
else if (tipoCliente == "Estudante")
{
return valorCompra * 0.05m;
}
else
{
return 0;
}
}
}

Padrão Strategy

O padrão Strategy permite definir uma família de algoritmos, encapsulá-los e torná-los intercambiáveis. Vamos aplicar este padrão ao código legado.

Passo 1: Definir uma interface para as estratégias de desconto

public interface IDescontoStrategy
{
decimal Calcular(decimal valorCompra);
}

Passo 2: Definir as classes concretas

public class DescontoRegular : IDescontoStrategy
{
public decimal Calcular(decimal valorCompra)
{
if (valorCompra > 1000)
{
return valorCompra * 0.10m;
}
return valorCompra * 0.05m;
}
}

public class DescontoVIP : IDescontoStrategy
{
public decimal Calcular(decimal valorCompra)
{
if (valorCompra > 1000)
{
return valorCompra * 0.20m;
}
return valorCompra * 0.15m;
}
}

public class DescontoEstudante : IDescontoStrategy
{
public decimal Calcular(decimal valorCompra)
{
return valorCompra * 0.05m;
}
}

public class SemDesconto : IDescontoStrategy
{
public decimal Calcular(decimal valorCompra)
{
return 0;
}
}

Agora é só refatorar a classe principal para utilizar as estratégias

public class CalculadoraDesconto
{
private readonly Dictionary<string, IDescontoStrategy> _descontos;

public CalculadoraDesconto()
{
_descontos = new Dictionary<string, IDescontoStrategy>
{
{ "Regular", new DescontoRegular() },
{ "VIP", new DescontoVIP() },
{ "Estudante", new DescontoEstudante() },
{ "Outro", new SemDesconto() }
};
}

public decimal CalcularDesconto(string tipoCliente, decimal valorCompra)
{
if (_descontos.TryGetValue(tipoCliente, out var descontoStrategy))
{
return descontoStrategy.Calcular(valorCompra);
}
return 0;
}
}

Como funciona?

Temos a classe “CalculadoraDesconto” que é responsável pela aplicação das regras de negócio.

Foi criado um Dictionary (estrutura chave/valor) que faz um vínculo com a palavra chave “Regular” e a Classe responsável pela sua regra, ao inicializar a classe, seu construtor instancia as regras x classes e fica pronto para efetuar a decisão que será feita pelo método “CalcularDesconto”. (Obs: isto pode melhorar, poderíamos ter utilizado um enum aqui mas isso é outra história e não tem a ver com o padrão strategy).

O Método “CalcularDesconto” por sua vez, utiliza o dicionário para identificar no dicionário, qual a classe que está ligada ao tipo de cliente aqui, onde você pode ver que o comando “TryGetValue” tenta obter no dicionário uma regra associada à “tipoCliente” que foi recebido como parâmetro:

public decimal CalcularDesconto(string tipoCliente, decimal valorCompra)
{
if (_descontos.TryGetValue(tipoCliente, out var descontoStrategy))
{
return descontoStrategy.Calcular(valorCompra);
}
return 0;
}

Pronto! assim seu código fica muito mais bonito e legível, permite maior facilidade para a inclusão de novas regras, e também a implementação de testes unitários aplicados à cada regra individualmente.

No próximo Post da série trarei outras dicas para melhorar o código !

Gostou do artigo? clique no ícone👏e me siga para ver as próximas publicações !! Quer ver mais conteúdos, acesse minhas redes através do Linktree: https://linktree.com/nizzola

--

--

Marcio Nizzola

Microsoft MVP | Software Architect na CI&T | Prof. da Etec Itu | Membro Fundador da Comunidade Itu Developers.