O que é Complexidade Ciclomática?
Complexidade ciclomática de um código é uma medida quantitativa criada por Thomas McCabe para mensurar quantos caminhos linearmente independentes esse código possui.
No desenvolvimento de software, é uma medida muito utilizada para indicar a complexidade de um programa. Matematicamente a CC é definida pela seguinte fórmula: M = E - N + 2P; e para ser calculada, é utilizado o Gráfico de Fluxo de Controle (CFG - Control Flow Graph). Nesse sentido, E corresponde ao número de linhas no CFG, N ao número de nodes (nós) e P ao número de componentes conectados. Em sistemas simples, funções ou métodos, P sempre será igual a 1, entretanto, podemos querer medir a complexidade ciclomática de múltiplos sistemas de uma vez, e.g. medir a complexidade de todos os métodos de uma classe. Nesse caso, P será igual ao número de métodos em questão.
No exemplo acima, é possível identificar 7 linhas, 7 nós e apenas um componente, aqui entendido como um fluxo inteiro. Assim sendo, temos M = 7 - 7 + 2*1; M = 2. Nesse caso, a complexidade ciclomática desse bloco de código é 2, ou seja, existem dois caminhos linearmente independentes. O caminho onde B é maior que C, e o caminho onde B não é maior que C.
Ter um código complexo demais o torna difícil de entender, identificar e corrigir falhas, dificulta a execução de testes automatizados já que existem mais condições a serem testadas podendo levar a gaps na cobertura de testes. Além disso, códigos muito complexos exigem uma carga cognitiva maior para a sua compreensão, isto é, são difíceis de ler, visto que possuem uma lógica muito complexa e múltiplos caminhos de execução possíveis. Por consequência, também são difíceis de manter e aplicar alguma alteração sem que bugs sejam introduzidos.
Diante disso, ficam claros quais são os benefícios de termos uma métrica que indique a complexidade do código da nossa aplicação. Com a medida da complexidade ciclomática é possível identificarmos trechos de código que precisam estar mais modularizados, melhorando a qualidade, leitura e manutenibilidade. Ademais, conseguimos executar testes automatizados de forma mais eficaz, garantindo uma cobertura maior do nosso repositório, o que também auxilia na identificação de novos e/ou possíveis bugs antes de chegarem em ambiente de produção.