# Complexidade Ciclomática: o que refatorar a seguir

URL: https://whatshouldibuildnext.com/pt/journal/complexidade-ciclomatica-o-que-refatorar-ou-construir-a-seguir
Type: blog
Locale: pt
Published: 2026-08-01
Updated: 2026-08-27

---

> Aprende a medir e interpretar a complexidade ciclomática no teu projeto, e decide o que refatorar a seguir com ferramentas como SonarQube e CodeScene.

## Complexidade Ciclomática: como saber o que refatorar (ou construir) a seguir

A complexidade ciclomática mede o número de caminhos independentes numa função ou módulo. Um valor superior a 10 é um sinal claro: mais bugs, mais testes necessários, mais dificuldade de manutenção. Se não sabes por onde começar a refatorar o teu projeto, começa pelos módulos com maior complexidade ciclomática. Não é a métrica perfeita, mas é uma das mais diretamente acionáveis que existem.

**TL;DR:** A complexidade ciclomática conta os ramos de decisão no código. Acima de 10 por função, o risco de bugs aumenta de forma consistente. Ferramentas como SonarQube, CodeScene e Code Climate identificam automaticamente os pontos críticos. Prioriza pelo impacto em produção, não pelo valor absoluto da métrica.

## O que é exatamente a complexidade ciclomática

Thomas McCabe definiu esta métrica em 1976, num artigo publicado nas IEEE Transactions on Software Engineering. A base teórica vem da teoria dos grafos: cada função pode ser representada como um grafo de fluxo de controlo, onde os nós são blocos de código sequencial e as arestas são transições possíveis entre eles.

A fórmula completa é `M = E - N + 2P`, onde E é o número de arestas, N o número de nós, e P o número de componentes conexos (geralmente 1 para uma função isolada). Na prática, existe um atalho mais direto: conta o número de pontos de decisão na função e adiciona 1.

`def processar_pedido(pedido):          # M começa em 1
    if pedido.urgente:                 # +1 -> M = 2
        notificar_equipa()
    for item in pedido.itens:          # +1 -> M = 3
        if item.stock == 0:            # +1 -> M = 4
            pedir_reposicao(item)
    return pedido`Esta função tem complexidade 4. Gerível. Uma função real de 300 linhas com vários `if` encadeados, múltiplos `try/except`, e lógica de negócio acumulada ao longo de anos pode chegar facilmente a 35 ou 50.

Cada `if`, `elif`, `else if`, `for`, `while`, `case`, `catch`, `and`, `or` e operador ternário conta como um ponto de decisão adicional. Em Python, o `radon` calcula isto automaticamente. Em JavaScript, o ESLint tem uma regra dedicada. Em Java, o Checkstyle e o PMD têm detetores nativos.

## Os limiares que realmente importam no dia a dia

Os valores de referência mais usados pela indústria:

- 
**1-10:** código simples, fácil de testar sem grande esforço.

- 
**11-20:** moderado; vale a pena monitorar a evolução ao longo dos sprints.

- 
**21-50:** complexo; cobertura de testes obrigatória antes de qualquer modificação.

- 
**Acima de 50:** praticamente impossível de testar de forma exaustiva; refatoração prioritária.

O limite de 10 não é uma lei da natureza. É um ponto de equilíbrio empiricamente identificado em múltiplos estudos sobre bases de código industriais. Em projetos legacy com décadas de histórico, uma função de complexidade 20 pode ser o melhor resultado possível após uma refatoração parcial -- e já é um ganho real.

O que importa mais do que o valor absoluto é a tendência: complexidade a aumentar sprint após sprint é um sinal de que a base de código está a degradar-se mais depressa do que está a ser mantida. Um dashboard de tendência temporal vale mais do que um snapshot único.

![Visualização dos caminhos de execução possíveis numa função com alta complexidade ciclomática](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/whatshouldibuildnext/2026-08/aec123-inline1.webp)

## Por que a complexidade ciclomática está associada a bugs

A relação não é teórica. Estudos sobre bases de código C++, Java e Python em contextos industriais mostram uma correlação consistente: módulos com complexidade acima de 20 apresentam entre 3x e 5x mais defeitos por linha de código do que módulos com complexidade abaixo de 10.

O mecanismo é direto. Mais caminhos de execução significa mais combinações de entradas a cobrir em testes. Cada caminho não coberto é um bug potencial que só se manifesta quando um utilizador ou processo específico aciona esse caminho em produção. Não é uma questão de qualidade do programador -- é física do código.

Em equipas, a complexidade elevada tem um custo adicional: o tempo de onboarding. Um dev que entra num projeto e encontra uma função de complexidade 40 vai demorar duas a três vezes mais a compreender o que acontece do que se a função tivesse complexidade 8. Durante esse período de compreensão incompleta, a probabilidade de introduzir um bug ao modificar a função é significativamente mais alta.

Num estudo sobre o código-fonte do OpenBSD publicado em 2009, módulos com complexidade ciclomática média acima de 15 tinham uma densidade de bugs 4.6x superior à dos módulos com complexidade abaixo de 6. Estes números variam por linguagem e domínio, mas a direção é consistente em projetos de dimensão real.

## Como calcular a complexidade ciclomática no teu projeto hoje

Antes de refatorar seja o que for, tens de saber onde estás. Sem medição, a refatoração é baseada em intuição -- que costuma apontar para o código que o dev mais detesta, não para o código que mais beneficiaria de atenção.

Não precisas de fazer nada à mão. As ferramentas calculam automaticamente:

**Python:** `radon cc src/ -a -s` retorna a complexidade média por módulo com classificação de A (baixo risco) a F (alto risco). Instala com `pip install radon`.

**JavaScript e TypeScript:** configura a regra `"complexity": ["error", 10]` no teu `.eslintrc`. Qualquer função que ultrapasse 10 falha o lint automaticamente.

**Java e Kotlin:** o Checkstyle tem a regra `CyclomaticComplexity`. O PMD tem a mesma regra na categoria `design`. Ambas configuram-se via XML e integram com Maven e Gradle.

**Go:** o `gocyclo` é a ferramenta padrão. `gocyclo -over 10 .` lista todas as funções acima do limiar definido.

Para projetos multi-linguagem ou equipas que querem visibilidade agregada num dashboard unificado, o SonarQube é a escolha mais completa. Integra com GitHub, GitLab, Bitbucket e Azure DevOps. O tier Community é gratuito para projetos open-source.

## Quando refatorar, quando monitorar e quando ignorar

A complexidade ciclomática elevada não obriga a uma refatoração imediata. A decisão racional passa por três critérios combinados:

**Frequência de modificação.** Um módulo com complexidade 30 que ninguém toca há dois anos tem risco operacional baixo. Um módulo com complexidade 15 que é modificado toda a semana é mais urgente. O historial de commits é um input crítico nesta decisão.

**Cobertura de testes.** Alta complexidade com 90% de cobertura é tolerável -- os caminhos estão verificados. Alta complexidade com 20% de cobertura é uma bomba de tempo: qualquer modificação pode quebrar um caminho não testado e o bug só aparece em produção.

**Impacto em produção.** Módulos no caminho crítico (autenticação, pagamentos, processamento de encomendas) têm prioridade máxima. Scripts de migração que correm uma vez por trimestre podem esperar.

O CodeScene automatiza esta análise combinada. Em vez de mostrar apenas "este módulo é complexo", mostra "este módulo é complexo, muda 3x por semana, e tem 25% de cobertura de testes". Isso é acionável.

## O que construir à volta desta métrica

Se trabalhas numa equipa pequena e queres um projeto interno com impacto imediato:

**Dashboard de tendência de complexidade.** Um script que corre `radon` ou `eslint` em CI, persiste os valores numa base de dados simples (SQLite ou Postgres), e renderiza um gráfico de tendência semanal por módulo. O valor prático: ver se a complexidade está a aumentar ou a diminuir ao longo dos sprints. Custo de construção: menos de um fim de semana.

**Bot de pull request.** Um GitHub Action que comenta automaticamente em PRs que introduzem funções com complexidade acima de 15. Não bloqueia o merge -- informa o autor e os revisores antes da revisão de código. Implementação: cerca de 80 linhas de Python mais um ficheiro de workflow YAML.

**Refactoring advisor.** Um script que passa o AST de uma função de alta complexidade para a API de um modelo de linguagem e pede sugestões de decomposição. Util para contextos com devs junior a aprender a escrever funções mais simples. Não substitui a revisão humana -- complementa-a nos primeiros anos de carreira.

Nenhum destes projetos requer um produto SaaS. São ferramentas internas com impacto mensurável e escopo limitado -- o tipo de projeto que se constrói, usa durante seis meses, e já valeu a pena independentemente de qualquer outra coisa.

![Dashboard de análise de complexidade ciclomática por módulo com evolução temporal](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/whatshouldibuildnext/2026-08/cf7628-inline2.webp)

## Code Climate como alternativa ao SonarQube

Para equipas que não querem gerir a infraestrutura do SonarQube -- que tem uma curva de setup não trivial, especialmente com autenticação e configuração de regras por linguagem -- o Code Climate Quality é uma alternativa gerida na cloud.

A integração com GitHub faz-se em menos de 10 minutos. Cada função recebe um rating de A a F com base na complexidade ciclomática e noutras métricas de duplicação e estabilidade. O dashboard agrega por repositório e mostra tendências temporais. A integração com PRs pode bloquear merges que pioram o rating global, configurável por threshold.

O limite do tier gratuito: repositórios públicos apenas. Para repos privados, o custo começa em torno de $25-50 por mês para uma equipa pequena. Razoável se substitui horas de análise manual e discussões recorrentes em code review sobre o que priorizar.

O próximo passo prático: escolhe uma ferramenta, corre-a no teu projeto hoje, e identifica as três funções com maior complexidade ciclomática. Depois decide, para cada uma, se a frequência de modificação e a cobertura de testes justificam refatoração imediata ou apenas monitorização. Provavelmente já tens a resposta antes de terminar a análise.

## FAQ

### O que é a complexidade ciclomática e como se calcula?

A complexidade ciclomática é uma métrica que conta o número de caminhos independentes numa função. Calcula-se somando o número de pontos de decisão (if, for, while, case, etc.) e adicionando 1. Uma função sem ramos tem complexidade 1. Ferramentas como radon (Python) ou ESLint (JavaScript) fazem este cálculo automaticamente.

### Qual é o valor máximo aceitável de complexidade ciclomática?

O consenso da indústria situa o limite em 10 por função. Acima de 10, a probabilidade de bugs aumenta de forma mensurável. Acima de 50, a função torna-se praticamente impossível de testar de forma exaustiva. Estes valores são guidelines, não regras absolutas: o contexto do projeto e a cobertura de testes influenciam a decisão.

### A complexidade ciclomática elevada é sempre razão para refatorar?

Não necessariamente. Complexidade elevada num módulo que não muda há dois anos tem risco baixo. Complexidade elevada num módulo modificado frequentemente e com baixa cobertura de testes é urgente. Combina sempre a métrica com o historial de commits e a cobertura de testes antes de decidir.

### O SonarQube calcula a complexidade ciclomática automaticamente?

Sim. O SonarQube calcula a complexidade ciclomática para todas as linguagens suportadas sem configuração adicional. O tier Community é gratuito para projetos open-source. Para projetos privados é necessário o tier Developer ou superior, com integração direta com GitHub e GitLab.

### Como a complexidade ciclomática ajuda a decidir o que construir a seguir?

Se geres uma base de código existente, começa pelos módulos com maior complexidade e maior frequência de modificação. Se estás a construir algo novo, define um limiar máximo de 10 no linting de CI desde o primeiro commit. Evitas acumular dívida técnica antes de a base de código crescer.

### O CodeScene é melhor do que o SonarQube para priorizar refatorações?

Para priorização, sim. O CodeScene combina complexidade ciclomática com análise de historial de commits e dados de equipa. Identifica automaticamente os pontos de maior risco real, não apenas os mais complexos em teoria. O SonarQube é mais completo como plataforma de qualidade geral; o CodeScene é mais específico para decisões de refatoração.

### A complexidade ciclomática funciona em todas as linguagens de programação?

O conceito é universal, mas a implementação varia por linguagem. A maioria das ferramentas de análise estática suporta as linguagens mais comuns: Python, JavaScript, Java, Go, C#, Ruby. Em linguagens funcionais como Haskell ou Erlang, a métrica é menos relevante porque o estilo favorece naturalmente funções curtas sem estado partilhado.