¿Dónde encajan las tecnologías para automatizar el desarrollo y asistir al desarrollador?

Jueves 15 septiembre 2022

Autores: 

¿Dónde encajan las tecnologías para automatizar el desarrollo y asistir al desarrollador?

¿Cómo se produce y opera el software en la práctica?

Las herramientas Low Code y No Code (por ej. Appinventor ‎[4] , Budibase ‎[5] , WebRatio ‎[3] , Figma ‎[6] , Debuild ‎[7] , etc.) nos permiten automatizar el desarrollo siguiendo un enfoque de diseño centrado en el usuario (utilizan interfaces gráficas y configuraciones fáciles de usar para crear las soluciones) ‎[1][2] . Además, existen herramientas tecnológicas de IA (por ej. GitHub copilot ‎[8] o OpenAI ‎[9] basadas en GPT3) que pueden usarse como asistente en las tareas de diseño y desarrollo de código. A continuación, para comprender mejor las implicaciones de estas tecnologías podrían tener en la producción y operaciones software, veremos cómo se llevan a cabo los proyectos software en la práctica y porqué cada vez cobra más fuerza que sigamos un enfoque de diseño orientado al usuario en contraste con el ciclo de vida clásico de desarrollo que todos conocemos (independientemente de si lo hacemos en cascada o de forma iterativa-incremental). Cualquiera que se haya enfrentado al diseño y desarrollo de un producto software, y más aún si el proyecto es de I+D, sabe de la incertidumbre inicial que tienen estos proyectos. El diseño y desarrollo de prototipos, permite que con poco esfuerzo, podamos adquirir conocimientos más rápidamente sobre la solución que se necesita. Además, cualquier cambio en el diseño exterior de un producto (sus interfaces) afectarán al diseño interior del producto, por lo que, no parece que tenga mucho sentido que diseñemos su interior antes de asegurarnos de que su diseño exterior no va a cambiar (o cambiará poco). Una vez que estamos seguros de que el exterior es “más estable”, podemos diseñarlo y construirlo de forma sistemática para que sea “útil” pero siempre, teniendo en cuenta que ofreceremos un servicio y que debemos asegurar ciertas “garantías”. La utilidad del artefacto es lo que estaría, principalmente, relacionado con los requisitos funcionales del producto mientras que la garantía (seguridad, capacidad, disponibilidad, continuidad, etc.) estaría más relacionada con lo que llamamos requisitos no funcionales. Al final, los requisitos, están presentes en todo el ciclo de vida del producto como se observa en la Figura 1.

Figura 1. Cómo se relacionan los requisitos en el ciclo de vida del producto.

Como comentábamos, independientemente del ciclo de desarrollo que sigamos (por ej. cascada o iterativo-incremental), tradicionalmente las etapas clásicas de un desarrollo de software, sin entrar en las operaciones, son: Elicitación de requisitos, Análisis de requisitos, Diseño, Construcción/Implementación, Pruebas. De hecho, las etapas anteriores son las que aparecen en las plantillas del ministerio que utilizamos los auditores para evaluar los proyectos que se realizan en nuestro país para calificar un proyecto como “innovación tecnológica” o “I+D”. En estos 3-4 años como evaluador, he podido evaluar más de 50 proyectos de este tipo. De forma breve, algunas de las cuestiones que he observado son:
 
Se mezcla el concepto de “Elicitación de requisitos” con el de “Análisis de requisitos”. La elicitación sólo debería cubrir la comprensión y definición del problema (por ej. un modelo de negocio que describa la realidad actual, solo para entender las necesidades), mientras que en el análisis, tendría que abordarse la solución de forma independiente a la tecnología (por ej. interfaces, diagrama de clases, diagrama de casos, diagrama de actividades, diagrama de secuencia, etc.).

Se mezcla el concepto de “Análisis de requisitos” con el de “Diseño”. Mientras que el análisis es genérico, el diseño es específico de la plataforma o la tecnología que se utilice para construir la solución. En la mayoría de proyectos evaluados, en el Diseño se incluyen diagramas de Análisis (es decir, genéricos, sin que se especifique tecnología alguna).

La documentación técnica no suele seguir ningún modelo de referencia, estándar o normativa (por ej. técnicas UML o BPMN). En este sentido, sería importante que se normalizara un mínimo de documentación técnica para este tipo de proyectos (cosa que estoy seguro que agradeceríamos todos los que evaluamos este tipo de proyectos).

Cuando se incluyen pruebas, suelen ser de baja calidad. Solo se aprecian actividades de verificación (pasado, después de diseñar y construir, asegurarnos de que hemos diseñado y construido la solución adecuada), siendo pocas la actividades de validación (futuro, antes de diseñar y construir, asegurarse de que la solución es la adecuada). Tampoco se mencionan actividades de monitorización continua (presente, asegurarse que el software funciona en tiempo real) ‎[10].

En algunos casos, se aportan pantallas que a veces, no sabes si son prototipos o capturas de pantalla reales del software desarrollado. No obstante, se suelen solicitar extractos de código como evidencias de que se llevó a cabo el desarrollo.
 

¿Qué estrategias podemos inferir a partir de la experiencia práctica como estrategia para la producción/operaciones software?
 

Si hacemos el esfuerzo de trasladar todas estas actividades a un modelo como el de la figura anterior, tendríamos algo como lo que se muestra en la Figura 2. En la siguiente figura, se ha considerado un ciclo de vida completo del producto software, desde su concepción (Discovery), siguiendo por su diseño y desarrollo (Development), hasta su puesta en producción como un servicio (Operations).
 
Figura 2.Ciclo de vida de producto (discovery,development,operations)
 
De forma muy resumida, los objetivos y las principales actividades, serían las siguientes:
 
Discovery: El objetivo es aprender cuanto antes sobre el problema y la solución, reducir la incertidumbre técnica y de negocio. Se consigue mediante la construcción y validación de un prototipo desechable (negocio) y pequeñas demos técnicas para ayudarnos a tomar decisiones sobre los componentes tecnológicos que utilizaremos en la construcción. Es una actividad de investigación y de generación de conocimientos.
Development: El objetivo es que la construcción sea lo más sistemática posible (no es ciencia, es ingeniería). Se consigue obteniendo un software que sea “útil” para sus usuarios y que haya sido probado en un entorno de desarrollo. Es una actividad donde se genera software.
Operations: El objetivo es poner a disposición de los usuarios el software para que puedan llevar a cabo sus actividades. Se consigue mediante la puesta marcha de un servicio que permita a los usuarios utilizar el software con “garantías”.
 
Si trasladamos las actividades de un ciclo de desarrollo clásico a este ciclo de vida de producto, nos daremos cuenta que no solo cubre Development. Por ejemplo, la elicitación de requisitos, encajaría en la comprensión y definición del problema. La actividad de Análisis de requisitos quedaría separada en dos actividades: (Discovery) aquellas que afectan a la definición externa de la solución (interfaces o prototipado) y (Development) aquellas relacionadas con la definición interna de la solución (diagrama de clases, diagramas de secuencia, etc.).
Las actividades de Diseño y Construcción, de igual manera, quedarían separadas en dos actividades: (Discovery) aquellas actividades que tienen como objetivo diseñar y construir una pequeña demo técnica y (Development) aquellas actividades que tienen como objetivo diseñar y construir el software.
La actividad de Pruebas (y podemos incluir monitorización continua si incluimos las operaciones), quedarían separada en tres: (Discovery) pruebas del sistema que pueden definirse usando los prototipos para “validar” el software mediante un prototipo desechable, (Development) pruebas unitarias y de integración que nos permiten “verificar” el software y, por último (Operations) monitorización continua que nos permite, en tiempo real, controlar y hacer un seguimiento del servicio que estamos ofreciendo.
 

Descubrimiento/Investigación, Desarrollo y Operaciones (Learn2Build vs Build2Learn)


Dependiendo de nuestro contexto, podrían darse diferentes situaciones que implicarían que podamos poner el foco más en Discovery (por ej. aplicando un proceso Design Thinking), o bien, en Development y Operations (por ej. aplicando el conjunto de buenas prácticas de DevOps).  

Figura 3. Discovery, Development & Operations.

El enfoque Learn2Build permite potenciar el aprendizaje previamente a la construcción. Es útil cuando nos encontremos en un contexto con una incertidumbre alta de negocio y técnica. Es decir, no tenemos claro cuál es problema, qué tenemos que construir ni como lo vamos a construir. Una estrategia que encajaría en este enfoque sería un proceso Design Thinking o la metodología Design Sprint ‎[12]. También encajarían los métodos de SAPIENS que veremos a continuación. La validación del artefacto (al menos sobre su utilidad, no su garantía) en etapas muy tempranas nos permite reducir los esfuerzos y el coste que implican encontrar posibles ventajas competitivas (que veremos más adelante y que es un concepto relacionado con la innovación).   

Figura 4. Enfoque Learn2Build.
 
Por otro lado, el enfoque Build2Learn permite potenciar la obtención de productos funcionales que aporten un valor real al usuario ‎[11]‎[13]. Sobre esto, es muy importante la definición de valor, y aquí habría que diferenciar el “Valor” que se aporta:
1. Si solo abordamos un “Desarrollo” donde el despliegue se lleva a cabo solo en un entorno de desarrollo y el usuario aún no puede sacarle partido al software del que se aporta 
2. Si además integramos las Operaciones” donde el despliegue se lleva a cabo tanto en entornos de pre-producción como en entornos de producción reales, permitiendo a los usuarios que utilicen el software bajo unas garantías de uso.
 
Además, este enfoque requiere que dispongamos de un equipo técnicamente muy maduro, ya que el coste de diseñar y construir soluciones software debe ser muy similar al diseño y construcción de un prototipo desechable. Además, también podría requerir la aplicación de unas mínimas estrategias de descubrimiento y gestión de requisitos (por ej. Lean Inception ‎[14] o Agile Inception), ya que es muy importante que se lleve a cabo una buena planificación para priorizar aquellas características funcionales (utilidad) y no funcionales (garantías) que preveemos que aportarían más valor al negocio.

Figura 5. Enfoque Build2Learn.

Con todo lo anterior, lo importante es que tengamos un equipo que, en cada momento se adapte a las circunstancias según el contexto como se muestra en la Figura 6, donde en un momento determinado podríamos empezar aplicando solo un enfoque Learn2Build (Discovery), en otro momento combinar ambos enfoques pero sin desplegar en producción (Discovery & Development), o bien, solo aplicar un enfoque Build2Learn desplegando en entornos de producción (Development & Operations).

Además es importante que se lleve a cabo una ejecución sistémica del proceso frente a lo que sería una ejecución improvisada. La principal diferencia es que tengamos clara nuestra estrategia (qué procesos y etapas de las anteriores llevamos a cabo) y nuestras tácticas (qué métodos, técnicas y artefactos software utilizas en esos procesos). Sobre esto último, os dejo una frase del Libro “El Arte de la guerra” de Sun Tzu que da lugar a la reflexión sobre estrategia y táctica en ingeniería del software: “Estrategia sin táctica es el camino más lento hacia la victoria, Las tácticas sin estrategia son el ruido antes de la derrota”.