Estimación: Juegos vistos como sistemas de software III

4 01 2009

Hoy voy a hablarles de algo llamado Complejidad Ciclomática (o Complejidad Condicional) es una forma de medir la complejidad lógica de una porción de código.

La misma se basa en el siguiente principio:

“Mientras mas variados sean los caminos que pueda tomar el flujo de ejecución de un programa, mas esfuerzo será necesario para idearlo, desarrollarlo y testearlo.” – Pablo Weremczuk*

Para dar un ejemplo mas cercano a la vida real, vamos a imaginar una función(como en C o javascript) y que esta función solo asigna valores a un puñado de variables. En ella no hay if’s, ni for’s, ni while’s ni ningún elemento que compare una variable con otra o con algún valor.

Por ser una función tan simple, no tiene bifurcaciones, por lo que con solo ejecutarla una vez, habremos recorrido todos los caminos que puede tomar el flujo del programa.

En este caso, la complejidad de la función es de 2(numero de bifurcaciones o “condiciones” + 1). Para facilitar las cosas, vamos a imaginar que contamos 1 por la declaración de la función y le sumamos otro 1, porque así lo dicen los libros.

Si en esta función tuviéramos un if(preguntar si una variable realmente tiene el valor que le indicamos), la complejidad de la función crecerá en 1. Ya que para recorrer cada camino posible que puede tomar el flujo de ejecución del programa necesitaremos correr la función al menos 2 veces. Por lo que la complejidad de dicha función nos queda de la siguiente manera:

Complejidad = 1 + 1 + 1 = 3

Los números 1 que se indican arriba corresponden a la declaración de la función, el camino principal(fuera del if) y el camino secundario(cuando se entra al if) respectivamente.

Ahora vamos a complicar un poco la cosa. Imaginemos que cada variable que recibe un valor dentro de esta función esta contenida dentro de una clase(como en java o C++). Entonces agregaremos un 1 a la cuenta por cada variable declarada y otro 1 por la declaración de la clase.

Así, la clase mas simple que podemos llegar a crear, es tan compleja como:

1 por la declaración de la clase
+
1 por cada declaración de variable.
+
1 por la declaración de la función(que puede ser el constructor).
+
1 por cada if que se encuentre dentro de la función.

Lo que nos da un total de 4 + (cantidad de declaraciones de variables) unidades de esfuerzo.

Para simplificar las cosas, solo mencioné los if’s, pero deben tenerse en cuenta todas las instrucciones que puedan aumentar la cantidad de caminos que puede seguir el flujo de ejecución de un programa. Incrementan en una UE(unidad de esfuerzo) la complejidad de un programa:

* Cada If
* Cada operador binario dentro de un if (and u or)
* Cada else/else if(misma consideracion con los and y or)
* Cada while, for, do, también contemplando los operadores lógicos.
* Cada declaración de variable, publica, provada o local(las variables dentro de un método).

¿Ok, para que nos sirve todo esto? Muy sencillo, esto nos sirve para poder determinar cuantas unidades de esfuerzo(en adelante UE) fueron necesarios para crear una determinada pieza de código.

Suficiente por ahora

Como decía un profesor: “Para una buena práctica, no hay nada mejor que una buena teoría”.

Así que dejo el tema acá para que asimilen este concepto. En la próxima entrega les explico como usar la complejidad condicional para estimar cuanto tiempo nos lleva desarrollar un juego, con una envidiable presición.

Como diría Leonard Nimoy: Adiós! y sigan mirando al cielo!

* Esta frase me la atribuyo a mi mismo, ya que es la definición mas compacta que pude idear para explicarles este principio que tantas alegrías me ha traído.