💧🧠 Elixir: Reduzindo a complexidade ciclomática
Tags: elixir, braziliandevs, refactorit, cyclomaticcomplexity
Published: 2022-05-14 04:00:23

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](https://linearb.io/blog/reduce-cyclomatic-complexity/)

* [O que é complexidade ciclomática?](#o-que-e-complexidade-ciclomatica)
* [Criando o projeto](#criando-o-projeto)
* [Exemplos de CC simples](#cc-simples)
 - [Função de complexidade 1](#complexidade-1)
 - [Função de complexidade 2](#complexidade-2)
 - [Função de complexidade 3](#complexidade-3)
   - [Reduzindo a CC](#reduzindo-a-cc)
* [Problemas futuros](#problemas-futuros)
 - [Complexidade cognitiva](#complexidade-cognitiva)
 - [Código mais difícil de testar](#codigo-mais-dificil-de-testar)
 - [Maior risco de defeitos](#maior-risco-de-defeitos)
* [Conclusão](#conclusao)

[![A Jornada do Autodidata em Inglês](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkoqkmh9hic17tnddjf6.png)](https://go.hotmart.com/R93865620U)

# O que é complexidade ciclomática? <a name="o-que-e-complexidade-ciclomatica">

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 <a name="criando-o-projeto">

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

```elixir
mix phx.new cyclomatic_complexity
```

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

```elixir
{:credo, "~> 1.6", only: [:dev, :test], runtime: false}
```
e rodando o comando abaixo no terminal:
```bash
$ mix deps.get
```

# Exemplos de CC simples <a name="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`:

```bash
$ mix credo gen.config
```

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:

```elixir
{Credo.Check.Refactor.CyclomaticComplexity, [max_complexity: 1]}
```

Você pode achar sobre isso na [documentação do credo](https://hexdocs.pm/credo/Credo.Check.Refactor.CyclomaticComplexity.html).


# Função de complexidade 1 <a name="complexidade-1">

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzjiklchg4fh5b1rg8nw.png)

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

# Função de complexidade 2 <a name="complexidade-2">

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctctcbb2mbhfd235dbul.png)

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hipmi90y6lt09pc4da02.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nz6ywhnwwnzwy803kz93.png)

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 <a name="complexidade-3">

Vamos aumentar a complexidade para 3:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0oewl9ef6rf1s6ta2xgz.png)
 
Agora existem três ramificações de execução possíveis.


# Reduzindo a CC <a name="reduzindo-a-cc">

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wup72r24tzlxmiw6vmz8.png) 

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 name="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 name="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 <a name="codigo-mais-dificil-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 <a name="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 <a name="conclusao">

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.