Compartilhar via


Métricas de código – Complexidade ciclomática

Ao trabalhar com métricas de código, um dos itens menos compreendidos parece ser a complexidade ciclomática. Essencialmente, na complexidade ciclomática, números mais altos são ruins e números mais baixos são bons. É possível usar a complexidade ciclomática para ter uma noção da dificuldade de qualquer código para testar, manter ou solucionar problemas, bem como uma indicação da probabilidade do código produzir erros. Em um alto nível, determinamos o valor da complexidade ciclomática contando o número de decisões tomadas em seu código-fonte. Neste artigo, é usado um exemplo simples de complexidade ciclomática para entender rapidamente o conceito e examinar algumas informações adicionais sobre o uso real e os limites sugeridos. Por fim, há uma seção de citações que podem ser usadas para obter detalhes desse assunto.

Exemplo

A complexidade ciclomática é definida como a medição da "quantidade de lógica de decisão em uma função de código-fonte" NIST235. Simplificando, quanto mais decisões precisarem ser tomadas no código, mais complexas serão.

Vamos ver isso tudo em ação. Crie um novo aplicativo de console e calcule imediatamente suas métricas de código em Analisar > Calcular métricas de código para solução.

Complexidade ciclomática - Exemplo 1

Observe que a complexidade ciclomática está em 2 (o valor mais baixo possível). Se você adicionar código de não decisão, observe que a complexidade não muda:

Complexidade ciclomática - Exemplo 2

Se você adicionar uma decisão, o valor da complexidade ciclomática aumentará em 1:

Complexidade ciclomática - Exemplo 3

Quando você altera a instrução if para uma instrução switch com 4 decisões a serem tomadas, ela vai do 2 para 6 original:

Complexidade ciclomática - Exemplo 4

Vamos dar uma olhada em uma base de código (hipotética) maior.

Complexidade ciclomática - Exemplo 5

Observe que a maioria dos itens, conforme você faz drill down na classe Products_Related, tem um valor de 1, mas alguns deles têm uma complexidade de 5. Por si só, pode não ser importante, mas dado que a maioria dos outros membros tem um 1 na mesma classe, você definitivamente deve analisar esses dois itens e ver o que está neles. Você pode fazer isso clicando com o botão direito do mouse no item e escolhendo Ir para o Código-Fonte no menu de contexto. Vejamos Product.set(Product):

Complexidade ciclomática - Exemplo 6

Considerando todas as instruções if, você pode ver por que a complexidade ciclomática está em um 5. Neste ponto, você pode decidir se é um nível aceitável de complexidade ou pode refatorar para reduzir a complexidade.

O Número Mágico

Assim como acontece com muitas métricas neste setor, não há um limite exato de complexidade ciclomática que atenda a todas as organizações. No entanto, NIST235 indica que um limite de 10 é um bom ponto de partida:

"O número preciso a ser usado como limite, no entanto, permanece um pouco controverso. O limite original de 10, conforme proposto por McCabe, tem comprovações de apoio relevantes, mas limites de até 15 também foram usados com sucesso. Os limites acima de 10 devem ser reservados para projetos que têm diversas vantagens operacionais em relação a projetos normais, por exemplo, equipe experiente, design formal, uma linguagem de programação moderna, programação estruturada, instruções de código e um plano de teste amplo. Em outras palavras, uma organização pode escolher um limite de complexidade maior que 10, mas somente se tiver certeza de que sabe o que está fazendo e estiver disposta a dedicar o esforço adicional de teste exigido por módulos mais complexos". NIST235

Complexidade ciclomática e Números de linha

Basta verificar o número de linhas de código por si só é, na melhor das hipóteses, um preditor muito amplo de qualidade de código. Há alguma verdade básica na ideia de que quanto mais linhas de código em uma função, maior a probabilidade de haver erros. No entanto, quando a complexidade ciclomática é combinada com linhas de código, há uma visão muito mais clara do potencial de erros.

Conforme descrito pelo Software Assurance Technology Center (SATC) na NASA:

"A SATC descobriu que a avaliação mais eficaz é uma combinação de tamanho e complexidade (ciclomática). Os módulos com alta complexidade e tamanho grande tendem a ter a menor confiabilidade. Módulos com baixo tamanho e alta complexidade também são um risco de confiabilidade porque costumam ser um código muito breve, o que é difícil de alterar ou modificar". SATC

Análise de Código

A análise de código inclui uma categoria de regras de manutenção. Para obter mais informações, confira Regras de manutenção. Ao usar a análise de código herdada, o conjunto de regras da Diretriz de Design Estendido contém uma área de manutenção:

Conjuntos de regras de diretrizes de design de complexidade ciclomática

Dentro da área de manutenção, há uma regra para complexidade:

Regra de manutenção da complexidade ciclomática

Essa regra emite um aviso quando a complexidade ciclomática atinge 25, portanto, pode ajudar a evitar complexidade excessiva. Para saber mais sobre a regra, consulte CA1502

Juntar as peças

A questão é que um número de alta complexidade significa maior probabilidade de erros com maior tempo para manter e solucionar problemas. Analise as funções que têm uma alta complexidade e decida se devem ser refatoradas para que se tornem menos complexas.

Citações

MCCABE5

McCabe, T. and A. Watson (1994), Software Complexity (CrossTalk: The Journal of Defense Software Engineering).

NIST235

Watson, A. H., & McCabe, T. J. (1996). Structured Testing: A Testing Methodology Using the Cyclomatic Complexity Metric (NIST Special Publication 500-235). Recuperado em 14 de maio de 2011, do site da McCabe Software: http://www.mccabe.com/pdf/mccabe-nist235r.pdf

SATC

Rosenberg, L., Hammer, T., Shaw, J. (1998). Software Metrics and Reliability (Proceedings of IEEE International Symposium on Software Reliability Engineering). Recuperado em 14 de maio de 2011, do site da Penn State University: https://citeseerx.ist.psu.edu/pdf/31e3f5732a7af3aecd364b6cc2a85d9495b5c159