¿Realmente es difícil hacer software? (y II)

En el artículo anterior se expuso que el software es un sistema complejo, así como las seis características principales de la complejidad inherente más la llamada complejidad accidental. Cierro la serie explicando cuáles son las leyes que rigen la evolución del software y respondiendo y reflexionando sobre la pregunta del título.

Características de la evolución del software

Una de las características innatas del software es la variabilidad, es decir, los constantes cambios a los que se somete. Meir Lehman formuló una serie de leyes de carácter empírico en 1974 –que ha ido ampliando y revisando– que describen el equilibrio entre las fuerzas que impulsan la evolución del software y aquellas que la frenan [3] [4] [5]. Hay un total de ocho leyes, pero antes de pasar a estudiarlas es necesario abordar un principio en el que se basan dos de ellas.

Principio de incertidumbre del software

«El resultado de la ejecución de un programa conlleva un grado de incertidumbre porque su resultado no puede predecirse de forma absoluta [6]».

La ejecución de un programa es admisible solo si el conjunto de los supuestos críticos hechos durante el desarrollo son válidos. Es un hecho que los ingenieros de software hacemos suposiciones [8]; es algo común y las realizamos a diferentes niveles: qué debe hacer el sistema, cómo funcionan los sistemas externos, cómo se comportará el usuario, cuál será su entorno operativo, suposiciones durante el diseño y la programación, etc.

Por ejemplo, se puede asumir que una aplicación que se va a ejecutar en una máquina que va a estar ubicada en una sala segura no va a necesitar control de acceso ni autenticación. El equipo de desarrollo necesita verificar que supuestos así, hechos a nivel de diseño, son válidos.

Normalmente, no es posible demostrar la validez de todas las suposiciones porque no es posible identificarlas todas. Además, aquellas que pudieran identificarse podrían dejar de ser válidas al hacer modificaciones en la aplicación. Si no se han hecho las correcciones adecuadas en el sistema, mostrará un comportamiento inadmisible por muy correctas que fueran las ejecuciones en el pasado.

La incertidumbre puede venir incluso de un programa verificado correctamente, respecto a una especificación formal, a consecuencia de cambios en el dominio.

Imagínese que en 1986, el año de implantación del IVA (Impuesto sobre el Valor Añadido) en España, se entrega una aplicación de facturación y se asume que el tipo máximo –entonces del 12%– no va a cambiar. La aplicación funciona perfectamente y está libre de errores. En 1992, cuando aumenta el IVA, la aplicación seguirá funcionando perfectamente, pero su ejecución no es admisible porque el supuesto de invariabilidad del IVA ya no es válido.

Ley del cambio continuo

«Un programa debe adaptarse continuamente o cada vez será menos satisfactorio para el usuario».

Esta ley está estrechamente relacionada con el principio anterior. A medida que los usuarios se den cuenta de la imprecisión o el funcionamiento incorrecto de la aplicación, comenzará la demanda de soluciones.

El cambio es inevitable en el software como en cualquier sistema complejo. Sin embargo, la velocidad a la que se realizan los cambios y la intolerancia a que esos cambios no se apliquen es mayor que en otros sistema del mundo real.

Ley de la complejidad creciente

«A medida que un programa evoluciona su complejidad aumenta si no se dedican recursos para preservarla o mantenerla».

La necesidad de adaptación del software provoca la aplicación continua de cambios que dan lugar a un aumento de las dependencias de sus elementos de manera desestructurada, lo que conduce al incremento de la complejidad del mismo.

Si no se ponen medios y se realiza un esfuerzo real para mantener la unidad e integridad del diseño, el bajo acoplamiento y la alta cohesión de sus elementos –limitando así el aumento de la complejidad– el coste necesario para mantener el sistema en estado óptimo será cada vez mayor pudiendo, incluso, terminar siendo inservible.

Ley del crecimiento continuo

«El contenido funcional de un programa debe aumentar continuamente durante su vida útil para mantener la satisfacción del usuario».

A la hora de desarrollar un nuevo sistema, la primera información que se necesita es la descripción detallada de la aplicación en su dominio operativo, que es la base y la fuente de definición de los requisitos del sistema. Los requisitos deben acotarse y limitarse debido a limitaciones como el plazo de entrega y el coste, lo cual puede conducir a la exclusión explícita o implícita de cierta funcionalidad o comportamiento deseado. Estas omisiones, tarde o temprano, provocarán la demanda de cambios porque los usuarios tendrán que intervenir activamente para realizar tareas que no están automatizadas.

Los sistemas crecen inevitablemente con el tiempo impulsado por los comentarios de los usuarios y todas las partes interesadas.

Ley de la autorregulación

«El proceso de evolución de un programa se autorregula con una distribución casi normal de las medidas de los atributos del sistema».

Existe un equilibrio entre aquello que se quiere cambiar y lo que se logra cambiar. Los atributos del sistema como la complejidad ciclomática, la falta de cohesión, los niveles de herencia, el número de clases, el nivel de acoplamiento entre objetos, el número de funciones o el número de variables, no sufren variaciones significativas en cada versión del programa.

Ley de conservación de la estabilidad organizativa

«La tasa media de actividad efectiva de un sistema en evolución es invariable a lo largo de la vida del producto».

El ritmo de desarrollo de un sistema es independiente del aumento de los recursos destinados a tal fin. La consecución de resultados satisfactorios depende de los atributos del sistema como su complejidad, plazos, errores detectados y todo tipo de métricas. El hecho de añadir más recursos puede reducir la productividad como consecuencia del aumento de la complejidad de la gestión, comunicación, disminución de la calidad del proceso y el aumento del gasto. La productividad de un nuevo miembro de un equipo puede llegar a ser incluso negativa porque, no solo necesitará tiempo para adquirir el conocimiento necesario para trabajar de forma efectiva y eficiente, requerirá del tiempo del personal que ya trabaja así.

En la práctica, la decisión de una organización de aumentar la actividad de desarrollo de un sistema se supedita a los atributos mencionados y, se ha demostrado estadísticamente, que da lugar a una tasa de actividad similar.

La ley de conservación de la estabilidad organizativa está relacionada con la ley de Brooks [2] de 1975: «Añadir más efectivos a un proyecto con retraso, lo retrasará aún más».

Ley de conservación del conocimiento

«Durante la vida activa de un programa en evolución, el contenido de las sucesivas versiones es estadísticamente invariable».

Cuantos más cambios y ampliaciones se lleven a cabo en una determinada versión de una aplicación, más difícil será que el equipo y otras partes interesadas sean conscientes y entiendan cuál es el objetivo de los cambios.

El ritmo de adquisición del conocimiento necesario por parte de todos los implicados influye en –incluso limita– la productividad y la calidad del desarrollo. Cuanto mayor sea el volumen de trabajo, más costará adquirir el conocimiento necesario para hacerlo.

Ley de disminución de la calidad

«Un programa se percibirá como de calidad decreciente a menos que se mantenga adaptado a su entorno operativo».

Esta ley también está relacionada con el «Principio de incertidumbre del software»: la incertidumbre aumenta con el tiempo a no ser que se procure detectarla y rectificarla como parte de la actividad de mantenimiento. También es consecuencia de que la familiaridad de los usuarios con una aplicación genera rechazo, es decir, a media que pasa el tiempo los usuarios se vuelven más expectantes y perceptivos –adquieren mayor grado de crítica– y, según hay más productos disponibles en el mercado, su criterio de aceptación cambia. Dicho de otro modo: una aplicación que en su día fue vanguardista, visualmente atractiva y fácil de usar –según la crítica de los propios usuarios– puede da lugar a un cambio de opinión al aparecer nuevas tecnologías y aplicaciones que hagan uso de ellas.

La calidad última del producto debe estar acorde con la satisfacción del usuario. Por tanto, la calidad del software disminuye con el tiempo.

Ley de retroalimentación del sistema

«Los procesos de desarrollo constituyen sistemas de retroalimentación multiciclo y multinivel y deben ser tratados como tales para mejorarse o modificarse con éxito».

La evolución del software es un proceso complejo en el que deben recogerse las opiniones de los usuarios, gestores y todas las partes interesadas, así como recabar información del análisis del entorno de ejecución y del dominio de la aplicación para lograr una mejora significativa del producto durante el proceso de evolución.

Ley de conservación de la complejidad

Tras exponer las ocho leyes de la evolución del software de Lehman, creo que es interesante hablar de la ley formulada por Larry Tesler [9] a mediados de los ochenta mientras trabaja en el mítico centro de investigación de Xerox en Palo Alto, California: el Xerox PARC.

«Toda aplicación tiene una cantidad de complejidad irreducible que no puede eliminarse ni ocultarse».

Tras el enunciado de la ley, Tesler se preguntaba quién debería tratar con esa complejidad: el usuario o el ingeniero. Dan Saffer [7] proporciona un excelente ejemplo para entender la ley. Si un cliente de correo electrónico debe establecer automáticamente la dirección del remitente, la complejidad se traslada al ingeniero; mientras que si debe hacerse a mano, la complejidad se traslada al usuario. La ley de Tesler está muy ligada al diseño de interfaces de usuario o a la experiencia de usuario en general. No en vano, fue en el Xerox PARC donde se inventaron las interfaces gráficas.

No obstante, la ley es válida desde otros puntos de vista. Por muchos recursos que se destinen a simplificar un sistema, llegará un momento en el que la complejidad no podrá reducirse más. Me pregunto entonces ¿qué actividad del desarrollo de software debería tratar con esa complejidad irreducible: el diseño o la programación?

Relacionada con esta ley hallamos un principio enunciado hace casi setenta años.

Principio de la variedad necesaria

Formulado por Ross Ashby en 1956 [1], el principio dice: «Solo la variedad puede absorber la variedad».

El término variedad hace referencia al número de elementos distinguibles de un conjunto. En pocas palabras, el principio viene a decir que un problema complejo requiere una solución compleja y no es posible resolverlo con una solución sencilla. Por ejemplo, si un problema necesita de diez estados para poder resolverse, la solución deberá contemplar al menos diez estados siendo éste el número óptimo. Normalmente, profesionales poco avezados lo solucionarán con un número de estados mayor.

Conclusiones y reflexiones

El conocimiento de un dominio ajeno al propio es –en mi opinión– el principal hecho diferenciador de nuestra profesión respecto a las demás. Como se ha expuesto, es el principal motivo que aducen los profesionales cuando se les pregunta por qué un proyecto ha fracasado o ha acabado con serios problemas. Los ingenieros no saben exactamente qué tienen que hacer porque muchos requisitos son ambiguos, están llenos de lagunas o, simplemente, es difícil entenderlos al estar escritos usando el lenguaje del dominio.

No nos engañemos, este problema no se soluciona convirtiendo a los informáticos en expertos en el dominio porque implicaría estudiar otras profesiones y porque a lo largo de nuestra vida profesional el dominio funcional de las aplicaciones que desarrollaremos cambiará varias veces.

Necesitamos hacer uso de nuestra capacidad de abstracción para extraer la esencia del dominio y desechar todos los detalles superfluos. Como informático, una de mis obligaciones es «ver» la información que debe procesar una máquina y abstraerme lo máximo posible. La abstracción es el mecanismo principal que tenemos para hacer frente a la complejidad.

Sin embargo, la capacidad de abstracción tiene un límite y varía mucho de unas personas a otras. Conozco compañeros que necesitan descender a los detalles y ver concreciones para llegar al entendimiento. Esto no los convierte en malos profesionales –ni muchísimo menos– simplemente refleja el hecho de que el ejercicio de abstracción es muy complicado pero, siendo el software invisible e intangible, qué es sino pura abstracción.

Respecto a la gestión de los proyectos, el mero hecho de encontrar el número exacto de personas para realizar un determinado volumen de trabajo en el tiempo estimado ya es, de por sí, todo un reto. Como hemos visto, un número demasiado grande puede hacer caer la productividad del equipo en picado y uno demasiado pequeño puede ser insuficiente para completar el trabajo en el plazo fijado.

Por todo lo visto, puedo concluir diciendo –sin temor a caer en la hipérbole– que el software es una de las actividades más complejas a las que se haya enfrentado nunca el ser humano.

Sin embargo, la percepción popular es bien distinta: hacer software no es un ingeniería, es programar y programar puede hacerlo cualquiera que reciba un mínimo de formación.

Recuerdo que hace unos años mi mujer y yo fuimos a renovar el pasaporte. Nos atendió un funcionario muy amablemente y mientras hacía los trámites me preguntó dónde trabaja y a qué me dedicaba. —Trabajo en […] y me dedico a hacer software —contesté. —¡Ah! —exclamó porque conocía la empresa—. Pues yo creía que allí todos eráis ingenieros… No respondí. Cuando salimos mi mujer me preguntó por qué no le había dicho que yo también lo era. No lo hice porque soy consciente de que, cuando Dios repartió la diplomacia, no llegué de los primeros. Siendo así, mi réplica podría haber estado fuera de lugar; algo que aquel buen hombre de ninguna manera merecía.

El concepto de aquel funcionario es el que tiene la gente corriente sobre la informática y no es culpable por pensar de esa manera, ya que se informan a partir de lo que dicen aquellos que, supuestamente, saben. En consecuencia, esto implica que profesionales con poder e influencia en nuestro sector llevan muchas décadas sin entender qué es el software y su tremenda complejidad, pero –lo más grave– es que creen que saben.

Personalmente, estoy harto del desprecio por la informática que hay en un país como España donde, incluso algunos directivos de grandes multinacionales siguen creyendo que para hacer software basta con un grupo de chavales que estén dispuestos a programar como unos locos. Humildemente les aconsejaría que se informaran sobre las particularidades del software. Hay aspectos que se enseñan en un máster en administración de empresas que, de ninguna manera, pueden aplicarse a nuestra profesión porque es muy diferente al resto.

No se sorprendan cuando los proyectos acaben con problemas y si, en lugar de hacer un análisis formal y serio de lo sucedido para buscar soluciones, siguen pensando que no se ha cumplido con el plazo por una simpleza como que «los chicos» no dieron la talla, lamento decirles que conclusiones como ésta denotan una ignorancia supina.

Ahora bien, nosotros –los profesionales– debemos hacer un esfuerzo activo para ganarnos el respeto de los demás. Cuando reducimos nuestra profesión a la programación, por mal camino vamos. El término «desarrollador» me produce rechazo y lo hace por varios motivos: porque es un palabro, porque suena horrible y porque oculta el término ingeniero. Acudan, por ejemplo, a la definición de «desarrollador de software» de la Wikipedia. Si nos ocupamos del análisis, diseño y programación somos ingenieros, nada de «desarrolladores». El término ingeniero lo entiende todo el mundo, el otro casi nadie. Mandemos un mensaje claro de lo que somos y si somos programadores, pues tal cual, es una profesión dignísima y muy exigente.

Claro que cuando algunos supuestos gurús del mundo de la informática mandan el mensaje de que diseñar y documentar (valga la redundancia) es un desperdicio, y son los que popularizan términos como developer, qué podemos hacer.

Referencias

[1] W. Ross Ashby. An Introduction to Cybernetics. Chapman & Hall, 1956.

[2] Frederick P. Brooks. The Mythical Man-Month. Addison-Wesley, 1975.

[3] Meir M. Lehman. «Laws of Software Evolution Revisited». En: Software Process Technology (1996).

[4] Meir M. Lehman. «On Understanding Laws, Evolution, and Conservation in the Large-Program Life Cycle». En: Journal of Systems and Software (1980).

[5] Meir M. Lehman. «Programs, Life Cycles, and Laws of Software Evolution». En: Proceedings of the IEEE, vol. 68(9) (1980).

[6] Meir M. Lehman. «Uncertainty in Computer Application and its Control Through the Engineering of Software». En: Journal of Software Maintenance: Research and Practice, vol 1 (1989).

[7] Dan Saffer. Designing for Interaction. New Riders, 2009.

[8] A. Steingruebl y G. Peterson. «Software Assumptions Lead to Preventable Errors». En: IEEE Security and Privacy, vol. 7(4) (2009).

[9] Jon Yablonski. Laws of UX: Using Psychology to Design Better Products & Services. O’Reilly, 2020.

Fotografía de la entrada por Chris Lawton en Unsplash

Entradas relacionadas