Clean Code - Early Return Principle(ERP)


  Hoje veremos o princípio - Early Return Principle - ou 'Princípio do Retorno Antecipado'.

O conceito 'Clean Code' (Código Limpo) é um conceito introduzido por Robert C. Martin em seu livro "Clean Code: A Handbook of Agile Software Craftsmanship."

É um conjunto de princípios e práticas de programação que tem como objetivo tornar o código-fonte mais legível, compreensível, manutenível e de alta qualidade. O "Clean Code" refere-se à criação de código de software de forma que seja fácil de entender e colaborar, reduzindo a complexidade e facilitando a manutenção a longo prazo.

Temos a seguir de forma bem resumida alguns dos princípios e práticas associadas ao Clean Code:

  1. Nomes Descritivos: Escolher nomes de variáveis, funções, classes e métodos que sejam descritivos e que revelem a intenção do código.
  2. Funções e Métodos Pequenos: Manter funções e métodos curtos e focados em fazer uma única coisa. Isso facilita a leitura e a compreensão do código.
  3. Comentários Significativos: Usar comentários quando necessário para explicar o porquê de uma determinada decisão no código, mas evitar comentários desnecessários.
  4. Evitar Código Morto: Remover código não utilizado ou redundante, evitando poluição do código.
  5. Formatação Consistente: Adotar uma convenção de formatação consistente para todo o código, tornando-o mais legível.
  6. Evitar Aninhamento Profundo: Reduzir aninhamento excessivo de estruturas de controle, como loops e condicionais, usando o "Early Return Principle" quando apropriado.
  7. Testes Automatizados: Escrever testes automatizados para garantir que as alterações no código não quebrem a funcionalidade existente.
  8. Dividir e Conquistar: Quebrar problemas complexos em problemas menores e mais gerenciáveis, usando funções e classes para encapsular partes do sistema.
  9. Manter o Acoplamento Baixo: Evitar dependências rígidas entre módulos e classes, promovendo a reutilização e a manutenção mais fácil.
  10. Revisão de Código: Realizar revisões de código entre membros da equipe para garantir que o código atenda aos padrões de qualidade.

Hoje vamos tratar com o  Early Return Principle (ERP) que nos ajuda a obter um código limpo.

O "Early Return Principle" (Princípio do Retorno Antecipado) é uma das diretrizes de programação que se encaixa no contexto das boas práticas para escrever código limpo. Esse princípio sugere que você deve evitar aninhar condicionais (if statements) profundamente em uma função ou método e, em vez disso, deve retornar imediatamente quando certas condições são atendidas.

A ideia por trás do "Early Return Principle" é melhorar a legibilidade do código, tornando-o mais claro e mais fácil de entender. Quando você encontra um caso onde a função não deve continuar executando devido a uma condição específica, em vez de aninhar instruções if e else para controlar o fluxo do programa, você deve simplesmente retornar o valor apropriado imediatamente.

Ao usar  aninhamentos excessivos de condicionais em vez de retornar antecipadamente estamos violando este princípio. A seguir temos um exemplo de violação :

public bool ContemNumeroPar(List<int> numeros)
{
  
bool contemPar = false;

  
if (numeros != null)
   {
     
if (numeros.Count > 0)
      {
         
foreach (int numero in numeros)
          {
           
if (numero % 2 == 0)
            {
                contemPar =
true;
               
break;
            }
        }
     }
 }
 
return contemPar;
}

Neste exemplo, estamos verificando se a lista numeros contém pelo menos um número par. No entanto, o código viola o "Early Return Principle" porque aninha várias condicionais. Isso torna o código mais complexo e menos legível do que poderia ser.

Podemos melhorar isso aplicando o "Early Return Principle" para tornar o código mais claro:

public bool ContemNumeroPar(List<int> numeros)
{
  
if (numeros == null || numeros.Count == 0)
   {
    
return false;
   }

   foreach (int numero in numeros)
   {
     
if (numero % 2 == 0)
      {
         
return true;
      }
    }
   
return false;
}

Melhorias:
- Código direto.
- Redução de aninhamento.
- Retorno imediato em caso de pré-condição inválida.

A seguir temos outro exemplo de código que esta aderente ao princípio:

public int CalcularIdade(DateTime dataNascimento)
{
  
if (dataNascimento == DateTime.MinValue)
   {
     
return -1; // Data de nascimento inválida
   }

    DateTime hoje = DateTime.Now;

    int idade = hoje.Year - dataNascimento.Year;

     if (hoje < dataNascimento.AddYears(idade))
    {
        idade--;
// Ainda não fez aniversário este ano
    }
   
return idade;
}

Destaque:
O uso do Early Return evita que a lógica principal seja executada em caso de dados inválidos.

Neste exemplo, o método CalcularIdade retorna antecipadamente com um valor de erro (-1) se a data de nascimento for inválida (por exemplo, DateTime.MinValue).

Isso evita que o restante da função seja executado desnecessariamente. Além disso, o código segue um fluxo claro e direto, tornando-o mais fácil de entender.

Para concluir veja este método :

public void ProcessarPedido(Pedido? pedido)
{
 
if (pedido != null)
  {
    
if (pedido.Verificado)
     {
       
if (pedido.Itens.Count > 0)
        {
          
if (pedido.Itens.Count > 25)
           {

             throw
new Exception( "O pedido " + pedido.Id + " possui muitos itens");
           }
          
if (pedido.Status != "Pronto")
           {
             
throw new Exception("O pedido " + pedido.Id + " não esta preparado");
           }
           pedido.Processado =
true;
         }
      }
   }
}

Fica evidente o aninhamento das instruções if que aplicam verificações de pré-condições.

Aqui vamos aplicar o princípio ERP usando um conjunto de cláusulas de guarda ou guard clauses.

public void ProcessarPedido(Pedido? pedido)
{
 
if (pedido != null)
      return;
 
 
if (pedido.Verificado)
     return;

 
if (pedido.Itens.Count > 0)
     return;

 
if (pedido.Itens.Count > 25)
      throw new Exception( "O pedido " + pedido.Id + " possui muitos itens");

 
if (pedido.Status != "Pronto")
     
throw new Exception("O pedido " + pedido.Id + " não esta preparado");

  pedido.Processado =
true;
}

Melhorou, mas podemos refiniar ainda mais o código mesclando as verificações em uma instrução if :

public void ProcessarPedido(Pedido? pedido)
{
 
if (pedido is null || !pedido.Verificado || pedido.Itens.Count == 0 )
     return;

 
if (pedido.Itens.Count > 25)
      throw new Exception( "O pedido " + pedido.Id + " possui muitos itens");

 
if (pedido.Status != "Pronto")
     
throw new Exception("O pedido " + pedido.Id + " não esta preparado");

   pedido.Processado =
true;
}

Podemos ainda criar um método auxiliar onde vamos verificar as condições prévias:

public void ProcessarPedido(Pedido? pedido)
{
 
if (PedidoPodeSerProcessado(pedido))
     return;

 
if (pedido.Itens.Count > 25)
      throw new Exception( "O pedido " + pedido.Id + " possui muitos itens");

 
if (pedido.Status != "Pronto")
     
throw new Exception("O pedido " + pedido.Id + " não esta preparado");

  pedido.Processado =
true;
}

static bool PedidoPodeSerProcessado(Pedido? pedido)
{
   return pedido is not null && pedido.Verificado && pedido.Itens.Any();

}

Assim, aplicar o Early Return Principle não é apenas uma questão de estilo. Ele:
- Melhora a legibilidade
- Reduz complexidade
- Ajuda na manutenção
- Favorece a extensão do código
- Previne erros por aninhamentos esquecidos

Essa prática se encaixa perfeitamente com outros princípios do Clean Code, como o SRP (Single Responsibility Principle) e o Open/Closed Principle.

E estamos conversados...

"Jesus disse-lhes: A minha comida é fazer a vontade daquele que me enviou, e realizar a sua obra."
João 4:34

Referências:


José Carlos Macoratti