Complejidad cognitiva

Complejidad cognitiva: métrica de software

Las métricas de complejidad (como la complejidad cognitiva) pueden ser utilizadas en el desarrollo, mantenimiento y reingeniería del software para estimar su riesgo, costo y estabilidad. Generalmente las más básicas contabilizan el tamaño del código (p.ej. número de líneas de código).

Sin embargo, desde un punto de vista basado en la calidad del software, cobra vital importancia la complejidad ciclomática. Esta métrica, propuesta por Thomas McCabe en 1976, se basa en el diagrama de flujo determinado por las estructuras de control de un determinado código. De dicho análisis se puede obtener una medida cuantitativa de la dificultad de crear pruebas automáticas del código y también es una medición orientativa de la fiabilidad del mismo. Esta métrica no obstante, está fuertemente vinculada al rendimiento del algoritmo “en su anfitrión” (el uso-máquina), pero no la mantenibilidad “en su implementación” (el uso humano). ¿Cómo podría medirse dicha complejidad? La respuesta a esta pregunta está en la complejidad cognitiva; la capacidad humana para comprender el algoritmo.

Complejidad cognitiva vs ciclomática

La complejidad ciclomática define el número de caminos independientes dentro de un fragmento de código y determina la cota superior del número de pruebas que se deben realizar para asegurar que se ejecuta cada sentencia al menos una vez. La relación porcentual entre esta cota y el número de iteraciones realizadas en un proceso de medición, se conoce como cobertura de código. De esta forma, un 100% de cobertura garantiza que todos los escenarios de un algoritmo han sido sometidos a pruebas unitarias.

complejidad en las diferentes estructuras de control
complejidad en las diferentes estructuras de control

Sin embargo, la implementación de un algoritmo no es necesariamente uniforme. Independientemente del lenguaje, existen múltiples implementaciones y no necesariamente tienen por qué cambiar su complejidad ciclomática. Veamos 2 ejemplos:

int sumOfPrimes(int max) {              // +1
  int total = 0;
  OUT: for (int i = 1; i <= max; ++i) { // +1
    for (int j = 2; j < i; ++j) {       // +1
      if (i % j == 0) {                 // +1
        continue OUT;
      }
    }
    total += i;
  }
  return total;
}                  // Cyclomatic Complexity 4
  String getWords(int number) { // +1
    switch (number) {
      case 1:                   // +1
        return "one";
      case 2:                   // +1
        return "a couple";
      default:                  // +1
        return "lots";
    }
  }        // Cyclomatic Complexity 4

Como podemos observar, la complejidad ciclomática en ambos casos es 4. No lo es sin embargo, la complejidad “humana” para mantener los dos códigos. El segundo es claramente más “asequible”. ¿Qué criterios podríamos usar para mejorar la métrica de complejidad cognitiva?

Complejidad cognitiva: 3 criterios principales

cognitive-complexity

  • Incrementar cuando hay salto en la línea (arriba-abajo, izquierda-derecha) de de lectura de flujo del código
  • Incrementar cuando las estructuras de control están anidadas
  • Ignorar “estructuras atajo” que por facilidad de lectura condensen múltiples líneas de código en una

Analicemos por tanto, según estos criterios:

                                // Cyclomatic Complexity    Cognitive Complexity
  String getWords(int number) { //          +1
    switch (number) {           //                                  +1
      case 1:                   //          +1
        return "one";
      case 2:                   //          +1
        return "a couple";
      default:                  //          +1
        return "lots";
    }
  }                             //          =4                      =1

Complejidad cognitiva: herramientas software

ciudad-sqale-rating (Complejidad cognitiva)
Ciudad 3D representando los nichos de complejidad y métricas de calidad de un software.

A la hora de analizar la complejidad cognitiva de un software, nuestro primer candidato sería seguramente SonarQube. (Pulsa aquí para descargar documentación) SonarQube, está ampliamente extendida en la comunidad de QA. Es usada como herramienta para calcular los umbrales de calidad, como la complejidad ciclomática.

Desde su blog “SonarSource” nos explican cómo están implementando esta métrica para los diferentes lenguajes (C/#/++, Java, JavaScript, etc), auque de momento el proyecto está en desarrollo.

Desde el departamento de operaciones de Axpe Consulting, hemos probado el plugin para proyectos python (ver plugin), liberado el 27 de Enero de 2017, descubriendo que ofrece un potencial de mejora en la mantenibilidad, de más de un 13% de la implementación de nuestros scripts en python.

¡Comparte!Email this to someoneTweet about this on TwitterShare on FacebookShare on Google+Pin on PinterestShare on LinkedInShare on Tumblr

1 Comment

  1. Gran artículo. Me ha servido mucho, pero me queda una duda. La imagen de la ciudad 3D que representa métricas de calidad de software, ¿qué es? Me parece bastante interesante pero no logro encontrar ninguna referencia en el texto. ¿Me podéis ayudar?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *