Las métricas en el mundo del software se pueden definir como elementos que proporcionan una medición cuantitativa de tangibles tales como el tamaño u otra característica de un software o sistema de información encaminado generalmente a realizar comparativas o planificaciones. Una de las métricas más importantes con la que contamos en el desarrollo es la complejidad, que puede ser usada en las fases de desarrollo o mantenimiento entre otras.
Dentro de la complejidad, en el mundo del software, la más usada, es la llamada complejidad ciclomática (McCabe , 1976), vital para darnos una idea de la calidad del software que se está desarrollando, aunque no es la única. McCabe pretendía hacer llegar la idea de que esta métrica nos guiaría a la hora de hacer algoritmos más testeables y mantenibles y, sin embargo, como veremos más adelante, son dos conceptos diferentes que requieren de distintos tipos de mediciones.
La complejidad ciclomática es la métrica que nos aporta cómo es de dificultosa la lógica de un programa, se basa en un grafo que representa el diagrama de flujo que viene determinado por la representación de las estructuras de control de un determinado programa. Del análisis de esta estructura se obtendrán las medidas cuantitativas que nos facilitarán la comprensión y mejora de las mismas.
La complejidad ciclomática, es una métrica que está fuertemente vinculada a cómo un algoritmo es de eficaz en un entorno de ejecución, pero no nos da la medida de otro factor que hay que tener en cuenta y que no es menos importante y es la mantenibilidad del mismo, es decir, como es de bueno un algoritmo para que una persona interactúe con él en su mantenimiento. Esto es la complejidad cognitiva.
La Complejidad Cognitiva es una medida de cómo es de difícil entender intuitivamente un bloque de código. A diferencia de la Complejidad Ciclomática, que determina qué dificultad tiene probar el código.
Para dejarlo un poco más claro veremos un ejemplo:
Ambos códigos tienen un complejidad ciclomática de 4. Sin embargo, el primero de ellos (imagen -2) tiene una mayor dificultad para ser mantenido debido al número de estructuras anidadas.Por lo que el esfuerzo humano destinado a su mantenimiento será mayor que el segundo. Al igual que ocurre con la ciclomática, la complejidad cognitiva se puede ponderar con un valor número que nos permita establecer comparativas y por ende mejoras en los algoritmos que nos lleven a crear programas más "entendibles" y "manejables" por el ser humano, con el ahorro en esfuerzo que esto implica.
Para establecer el valor de la complejidad cognitiva, se establecen algunos puntos en los cuales nos tenemos que fijar dentro de lo que es un algoritmo:
- Se incrementa cuando hay salto en el flujo del código (arriba-abajo, izquierda-derecha). Algunos elementos que incrementan la c. cognitiva son:
- loops
- conditionals
- catching/rescuing exceptions
- switch or case statements
- sequences of logical operators (e.g. a || b && c || d)
- recursión
- jumps to labels
- for
- Se incrementa cuando las estructuras de control están anidadas.
- El código no es más complejo por usar estructuras del lenguaje que nos permitan incluir en una sola línea varias sentencias.
Con los criterios que acabamos de comentar, en el algoritmo de la imagen-3, la complejidad cognitiva sería de 1 (imagen 5), mientras que la ciclomática es de 4.
En este caso la complejidad cognitiva en el caso del switch tiene valor 1, ya que es una estructura fácil de comprender y manejar. Sin embargo en el flujo de la imagen-4, al tener una serie de elementos anidados hace más difícil la comprensión para el desarrollador, por lo que la complejidad cognitiva aumenta. El hecho de que que el algoritmo de la izquierda de la imagen tenga una mayor complejidad cognitiva nos indica que será menos comprensible y de mayor dificultad a la hora de ejecutar cambios.
Una de las finalidades que busca la complejidad cognitiva es la de incentivar las buenas prácticas a la hora de codificar, para que de esta manera se tenga un producto más entendible y por lo tanto mantenible. Nos lleva a tener un criterio más a la hora de refactorizar una aplicación legacy.
Análisis automático de la complejidad cognitiva
Para el análisis automático de la complejidad cognitiva SonarQube tiene una regla que nos permitirá conocer su valor y de esta manera actuar sobre el bloque de código que no cumpla con los valores que hemos establecido en la herramienta:
En SonarQube dentro de un Quality Profile se define que por defecto los métodos no tengan una complejidad cognitiva mayor de 15.
Para conocer más en detalle cómo SonarQube calcula este parámetro podemos acceder a esta página. ¡Hasta la próxima!
Si te ha gustado, ¡síguenos en Twitter!