La complejidad ciclomática es una métrica clave utilizada para medir la complejidad estructural del código. Fue introducida por Thomas J. McCabe en 1976 y se utiliza para evaluar la cantidad de caminos lógicos posibles en un programa. Esta métrica no solo ayuda a identificar el nivel de dificultad para probar y mantener el código, sino que también indica la probabilidad de errores.

En este artículo, exploraremos qué es la complejidad ciclomática, su cálculo, los "números mágicos" asociados, y cómo usar esta métrica para mejorar la calidad del código. También incluiremos ejemplos en Java para ilustrar cómo medir y analizar la complejidad ciclomática.


¿Qué es la Complejidad Ciclomática?

La complejidad ciclomática mide el número de caminos linealmente independientes a través del código fuente de un programa. Se calcula a partir del flujo de control de un programa, basándose en el número de nodos, aristas y componentes conectados en el gráfico.

Fórmula

La fórmula básica para calcular la complejidad ciclomática es:

M = E - N + 2P

Donde:

  • M: Complejidad ciclomática.
  • E: Número de aristas en el gráfico.
  • N: Número de nodos en el gráfico.
  • P: Número de componentes conectados (en la mayoría de los casos es 1).

¿Por qué es Importante?

La complejidad ciclomática ayuda a:

  • Identificar código difícil de mantener: Los valores altos indican un mayor riesgo de errores.
  • Determinar la cantidad mínima de casos de prueba: Proporciona una guía para garantizar una cobertura adecuada de pruebas.
  • Promover la simplicidad: Incentiva la escritura de código más claro y modular.

Los "Números Mágicos"

Límites Recomendados

  • 1 a 10: Código simple y manejable.
  • 11 a 20: Código moderadamente complejo; se recomienda refactorización si es posible.
  • 21 a 50: Código complejo; difícil de probar y mantener.
  • Más de 50: Código extremadamente complejo; requiere una reescritura completa.

Ejemplo en Java

public class Ejemplo {

    public int calcularMaximo(int a, int b, int c) {
        if (a > b && a > c) { // Camino 1
            return a;
        } else if (b > c) { // Camino 2
            return b;
        } else { // Camino 3
            return c;
        }
    }
}

Cálculo de la Complejidad Ciclomática

  • Nodos: 4 (inicio, tres ramas de control).
  • Aristas: 5.
  • Componentes conectados: 1.
M = E - N + 2P = 5 - 4 + 2(1) = 3

Este método tiene una complejidad ciclomática de 3, lo que indica tres caminos lógicos independientes.


Métricas de Código

Otros Indicadores Importantes

  1. Número de líneas de código (LOC): Ayuda a evaluar el tamaño general del código.
  2. Número de métodos: Proporciona una idea del nivel de modularidad.
  3. Profundidad de anidación: Una anidación excesiva aumenta la complejidad y dificulta la legibilidad.

Análisis de Código

Herramientas para Medir la Complejidad Ciclomática

Existen herramientas que pueden calcular automáticamente la complejidad ciclomática:

  • SonarQube: Proporciona informes detallados sobre la calidad del código.
  • Eclipse Metrics Plugin: Un complemento para calcular métricas directamente en el IDE.
  • CodeClimate: Ofrece un análisis profundo de la calidad del código.

Ejemplo Avanzado en Java

public class ValidacionUsuario {

    public boolean validarUsuario(String nombre, int edad, String email) {
        if (nombre == null || nombre.isEmpty()) { // Camino 1
            return false;
        }
        if (edad < 18 || edad > 100) { // Camino 2
            return false;
        }
        if (!email.contains("@")) { // Camino 3
            return false;
        }
        return true; // Camino 4
    }
}
  • Nodos: 5.
  • Aristas: 6.
  • Componentes conectados: 1.
M = E - N + 2P = 6 - 5 + 2(1) = 3

Este método tiene una complejidad ciclomática de 3, lo que lo hace manejable.


Cómo Reducir la Complejidad Ciclomática

  1. Dividir funciones grandes: Extraer métodos pequeños para reducir la complejidad.
  2. Evitar estructuras de control anidadas: Utilizar técnicas como guard clauses.
  3. Adoptar un enfoque modular: Promueve la reutilización y mejora la legibilidad.

Ejemplo: Refactorización

Código Original:

public boolean validar(int a, int b, int c) {
    if (a > b && b > c) {
        return true;
    } else if (a == b && b == c) {
        return false;
    } else {
        return a > c;
    }
}

Código Refactorizado:

public boolean validar(int a, int b, int c) {
    if (a > b && b > c) return true;
    if (a == b && b == c) return false;
    return a > c;
}

Reducción de la complejidad sin afectar la lógica.


Conclusión

La complejidad ciclomática es una métrica esencial para evaluar la calidad del código. Entender y medir esta métrica permite identificar áreas problemáticas, mejorar la mantenibilidad y garantizar una cobertura de pruebas adecuada. Adoptar herramientas y prácticas recomendadas ayuda a mantener un código más limpio, simple y eficiente.


Referencias