¿Por qué el desarrollo de software es incierto y complejo?

programming

programming

La incertidumbre en un sistema o entorno, entendida como la falta de un modelo que nos permita predecir el comportamiento de un sistema, está directamente relacionada con la existencia de dinámicas complejas, la interpretación subjetiva y la ambigüedad en el entendimiento de la información acerca del sistema.

Si algo tiene el software son dinámicas complejas, las cuales son una de las principales fuentes de la incertidumbre en el desarrollo del mismo. Desde los años 70, la capacidad de cómputo es muy superior al cerebro humano consciente, tanto en volumen como en velocidad de cómputo.

Dicha capacidad ha crecido exponencialmente durante los últimos 40 años. Año tras año, hemos ido creando máquinas más potentes y complejas. Según las observaciones de George Moore, transformadas en la Ley de Moore , el número de transistores de una CPU se duplica cada dos años y, por tanto, también lo hace su potencia de cómputo.

Para manejar la complejidad de las máquinas se han creado sistemas operativos y lenguajes de programación de alto nivel que abstraen la complejidad del computador, estableciendo modelos representacionales o abstractos de la máquina que simplifican la tarea de programación de la misma.



Pero aun así, los programas tienen una dimensión temporal de ejecución, que hace que sea muy difícil para un cerebro humano predecir a priori el resultado de la ejecución de un programa o sistema software, especialmente cuando el problema a resolver es complejo y/o existen múltiples interacciones del software con humanos y/u otros sistemas, cada uno de ellos con su dimensión temporal de ejecución (a mucha velocidad) y estado con múltiples variables.

Un computador es en el fondo una máquina matemática y lógica, por tanto, predecible a priori. Sin embargo, la velocidad y paralelismo a la que ocurren sus procesos, junto con el volumen tanto de instrucciones como de datos procesados hace que para un cerebro humano sea muy difícil, poco práctico e incluso inviable, predecir su comportamiento cuando ejecuta programas.

Nuestro cerebro podría repetir uno a uno los pasos que realiza la máquina, pero no sería práctico cuando hay mucho volumen de instrucciones, interacciones y velocidad de ejecución. Al final, lo más práctico es ejecutar el programa, observar los resultados de su ejecución y evaluar si el comportamiento es el esperado.

Siempre que los humanos se enfrentan a problemas en entornos con dinámicas complejas, como es el caso del desarrollo software, es necesario intercambiar conocimiento e interpretar información de una forma creativa, tanto del problema a resolver como de sus posibles soluciones.

Por un lado, las interpretaciones de los humanos suelen ser subjetivas, basadas en su conocimiento y experiencia. Por otro, en muchas ocasiones las fuentes de información acerca del problema a resolver o su solución son ambiguas. Todo ello son causas de incertidumbre.

Para complicar aún más la situación de incertidumbre, a mayor número de humanos en un entorno de complejidad alta (el caso del software), donde es necesario alto conocimiento, interpretación de información y aplicar creatividad, mayores son las posibilidades de tener una alta incertidumbre. Esta situación podría explicar por qué los proyectos software, cuanto más grandes en número de personas, mayor probabilidad de fallo a la Standish.

Proyectos por encima de 10M$ de coste de personal, tienen una probabilidad de fallo del 98%, entre 3M$ y 750K$ tienen una probabilidad de fallo de 62%. Mientras que proyectos por debajo de 750K$ (un equipo de aproximadamente 6-7 personas/año) tienen la mayor probabilidad de éxito según los criterios de Standish” (un 62%).

Durante muchos años y aún en la actualidad, el desarrollo de software se ha entendido como un proceso que ocurre después de que haya una especificación o definición de dicho software, primero a nivel de usuario o externo (Use Cases, User Experience), luego a nivel interno (arquitectura, análisis y diseño del software) y finalmente la construcción o síntesis del software que viene dirigida por la definición previa.

Esta construcción incluye la programación, testing y despliegue del software. Este modelo waterfall que está presente en la mente de muchas personas, asume que el software puede ser definido y planificado a priori. Pero como hemos visto, la complejidad e incertidumbre hace que sea muy difícil disponer de un modelo predictivo tanto del proceso de desarrollo como del sistema software.

Lo normal es que un plan no se cumpla o que una especificación no se entregue o que una arquitectura definida a priori no funcione, tal como muestran los informes de Standish. En mi experiencia, solo hay una circunstancia en la que el desarrollo de software se puede predecir, por tanto, estimar con cierta precisión: cuando se trata de desarrollar un sistema que se ha construido previamente varias veces por el mismo equipo y en un contexto similar.

Es decir, cuando el equipo de desarrollo tiene experiencia previa en el problema, en su solución y en haber trabajado e interaccionado juntos. Pequeños cambios en el contexto de un proyecto alteran sustancialmente su probabilidad de éxito a la Standish, incluso aunque se siga el mismo proceso, plan o la misma arquitectura.

La principal dificultad en el desarrollo de software es que la incertidumbre está presente a la vez en varias mentes que tratan de resolver varias variables esenciales que se combinan entre sí: la definición del software o what, junto con su realización o how, ambas desde un punto de vista externo o del usuario y desde un punto de vista interno o de implementación tecnológica.

Todo ello combinando aspectos estructurales y de comportamiento en el tiempo. Todas estas variables what-how, externo-interno, estructura-comportamiento han de ser descubiertas concurrentemente y en cualquier orden durante el proceso de creación del software, lo cual hace que todo el proceso sea complejo e incierto.