DEV Community

Dev Maiqui 🇧🇷
Dev Maiqui 🇧🇷

Posted on • Edited on

💧🧠 Elixir: Reduzindo a complexidade ciclomática

Neste post vamos aprender o que é complexidade ciclomática, como identificá-la e quais os seus pontos negativos. Vamos usar bastante o Credo para identificar de fato a complexidade de cada exemplo fornecido.

Para este artigo foi usado como base How To Reduce Cyclomatic Complexity: A Complete Guide

A Jornada do Autodidata em Inglês

O que é complexidade ciclomática?

A complexidade ciclomática (CC) é uma métrica de complexidade de software intimamente correlacionada com erros de codificação.

Se uma função parece que ficou muito complexa, na maioria das vezes ela também tem um valor CC alto. Portanto, isso é útil para convencer os membros da equipe e os chefes da necessidade de refatorar partes do código com base em métricas "objetivas".

A complexidade ciclomática é o número mínimo de casos de teste necessários para alcançar a cobertura total da ramificação. Assim, a complexidade ciclomática pode prever o quão difícil é testar um determinado pedaço de código.

Vamos construir um projeto para testar alguns exemplos.

Criando o projeto

O projeto pronto você encontra em: https://github.com/maiquitome/cyclomatic_complexity

mix phx.new cyclomatic_complexity
Enter fullscreen mode Exit fullscreen mode

Quem verifica o CC é o Credo, então instale ele adicionando a linha abaixo ao seu mix.exs:

{:credo, "~> 1.6", only: [:dev, :test], runtime: false}
Enter fullscreen mode Exit fullscreen mode

e rodando o comando abaixo no terminal:

$ mix deps.get
Enter fullscreen mode Exit fullscreen mode

Exemplos de CC simples

Vamos criar uns exemplos bem simples de complexidade ciclomática e, por serem bem simples, vamos precisar configurar o Credo para identificar o CC delas.

Rode o comando abaixo no terminal para gerar o arquivo de configuração .credo.exs:

$ mix credo gen.config
Enter fullscreen mode Exit fullscreen mode

Agora no arquivo .credo.exs você pode configurar o max_complexity ao seu gosto (o padrão é 9). Vamos configurar o credo para aceitar apenas a complexidade 1, assim vai ser mais fácil criarmos exemplos, pois se a complexidade for maior que 1, o credo irá gerar um alerta para refatoração:

{Credo.Check.Refactor.CyclomaticComplexity, [max_complexity: 1]}
Enter fullscreen mode Exit fullscreen mode

Você pode achar sobre isso na documentação do credo.

Função de complexidade 1

Image description

Como tem uma única declaração, é fácil ver que sua complexidade ciclomática é 1.

Função de complexidade 2

Image description

Para a mensagem aparecer dessa forma no seu VSCode instale as extensões Error Lens e Linter.

Image description

Image description

A segunda versão da função tem uma ramificação. O chamador para a função pode passar true como o valor para o parâmetro say_goodbye, mesmo que o valor padrão seja false. Se isso acontecer, a função imprimirá uma mensagem de adeus após dizer olá. Por outro lado, se o chamador não fornecer um valor para o parâmetro ou escolher false, a mensagem de despedida não será exibida.

Assim, a função tem duas ramificações de execução possíveis, o que é o mesmo que dizer que ela tem um valor de complexidade ciclomática de 2.

Função de complexidade 3

Vamos aumentar a complexidade para 3:

Image description

Agora existem três ramificações de execução possíveis.

Reduzindo a CC

Vamos reduzir essa complexidade ciclomática de 3 para 1. Em Elixir conseguimos fazer isso facilmente:

Image description

Agora não temos mais o alerta do Credo, pois a complexidade ciclomática agora é de 1. Lembrando que o padrão do Credo é 9, então não precisamos reduzir sempre para 1, senão não conseguiríamos nunca usar uma estrutura de decisão como o case, cond, with.

Problemas futuros

A complexidade ciclomática não é intrinsecamente ruim. Por exemplo, você pode ter um pedaço de código com um valor complexo ciclomático um tanto alto que é super fácil de ler e entender.

No entanto, de modo geral, podemos dizer que ter uma complexidade ciclomática muito alta é um sintoma de problemas com a base de código ou uma causa potencial de problemas futuros. Vamos abordar algumas das razões pelas quais você deseja reduzi-la com mais detalhes.

Complexidade cognitiva

A complexidade cognitiva refere-se a quão difícil é entender um determinado pedaço de código. Embora nem sempre seja o caso, a complexidade ciclomática pode ser um dos fatores que impulsionam a complexidade cognitiva. Quanto maior a complexidade cognitiva de um pedaço de código, mais difícil é navegar e manter.

Código mais difícil de testar

Valores mais altos de complexidade ciclomática resultam na necessidade de um número maior de casos de teste para testar de forma abrangente um bloco de código – por exemplo, uma função. Portanto, se você deseja facilitar sua vida ao escrever testes, provavelmente deseja reduzir a complexidade ciclomática do seu código.

Maior risco de defeitos

É provável que você introduza defeitos em uma área da base de código que você altera muito do que em uma área onde raramente toca. Além disso, quanto mais complexo for um determinado trecho de código, maior a probabilidade de você o interpretar mal e introduzir um defeito nele.

Conclusão

Concluímos que a complexidade ciclomática (CC) nos ajuda a ter um código mais fácil de entender, mais fácil de testar e de dar manutenção; evitando problemas futuros. Não precisamos reduzir a CC para 1, mas precisamos ficar atentos a esses fatores.

Top comments (2)

Collapse
 
zoedsoupe profile image
Zoey de Souza Pessanha

ötimo post!!!!!

Collapse
 
maiquitome profile image
Dev Maiqui 🇧🇷

Obrigado pelo feedback :)