Archivo

Archivo de la etiqueta: ciclo de vida iterativo incremental

Hasta que el usuario no interacciona con el producto software no comprueba si sus expectativas están satisfechas.

Las expectativas van más allá de una visión funcional del software ya que es absolutamente fundamental que el usuario tenga una buena experiencia de uso. Tal vez usuarios con una gran capacidad de abstracción y que hayan dedicado mucho tiempo al proyecto puedan atisbar antes de interactuar con el producto si funcionalmente les satisface, pero la experiencia de uso no se tiene hasta que se utiliza.

Por ese motivo las metodologías clásicas no terminan de producir buenos resultados, ya que entienden que es posible acertar con todo desde el análisis y que si no, ya vendrá el mantenimiento. El problema que suele producirse en estos casos es que el presupuesto de mantenimiento no existe o de existir suele ser inferior a la envergadura de los cambios que van a ser necesarios.

El feedback del usuario es fundamental desde las etapas más tempranas posibles del desarrollo, de ahí la necesidad de ir construyendo y liberando el producto de manera progresiva.

Jim Horning lleva más de cuarenta años en este negocio dedicándose principalmente al campo de la investigación. Doctorado en Stanford, desarrolló los primeros años de su carrera laboral en la Universidad de Toronto, pasando después siete años en el Xerox Parc (entre 1977 y 1984), tras esa etapa siguió desarrollando su labor investigadora en otras entidades y centros.

Hay una cita de Horning, que refleja en gran medida la complejidad del trabajo que realizamos, ya sea cuando realizamos el mantenimiento evolutivo o adaptativo de un sistema o realizamos un desarrollo siguiendo un enfoque iterativo e incremental donde en cada iteración se pasan a producción partes funcionales del software: “La ciencia informática es la única disciplina en la que nosotros consideramos la construcción de una nueva ala a un edificio como si fuera un mantenimiento”.

Y es así, podemos cometer errores de gran impacto cuando se realizan modificaciones sobre un sistema en producción: funcionalidad mal implementada o mal especificada que puede afectar a una función de negocio importante, efectos colaterales, etc… y que después pueden obligar a tener que actuar con urgencia lo que a la vez puede traer consigo nuevos problemas.

El desarrollo de software es así, tal vez por eso nos gusta tanto a la par de que nos trae muchísimos (demasiados) problemas.

Si el usuario no tiene en cuenta lo que cuesta cambiar de opinión, equivocarse y en general la adaptación de la solución disponible en cada iteración a una que se aproxime cada vez más a sus expectativas estamos entrando en el juego peligroso de la barra libre ficticia, ya que llegará un punto donde por parte del proveedor no se pueda asumir más gasto y generalmente se avisará al cliente demasiado tarde (siempre será demasiado tarde).

Cuando se llega a esa situación el resultado en la mayoría de los casos será desgaste por ambas partes y un producto final que no dejará contento a nadie.

¿Una posible estrategia? Que el cliente (tanto el responsable técnico como los responsables usuarios) tengan conocimiento y estén de acuerdo con el coste que tiene llevar a cabo las especificaciones realizadas en cada iteración (una por una) y que como se partirá de un presupuesto de partida fijo a cambio de qué se llevan a cabo esos ajustes (ver artículos relacionados con la contratación ágil).

No se trata de poner al cliente o al usuario bajo la presión de tener que acertar siempre, eso no sería ni realista ni ágil, sino de que entiendan que se tienen que tomar muy en serio su rol en el proyecto y que la evolución del producto no se lleva a cabo mediante prueba y error, sino con intención.

La resistencia vista desde distintas perspectivas, como por ejemplo el tiempo de más que tarda en pasarse a producción un producto o todas aquellas dificultades u obstáculos extras en el proceso de desarrollo, que puede ir desde la deuda técnica hasta la falta de colaboración por parte de los usuarios, dificulta el establecimiento de ciclos cortos en un enfoque iterativo e incremental.

Esto al final es como la pescadilla que se muerde la cola, ya que cuanto más largo sea el ciclo, mayor número de funcionalidades se incorporarán o se modificarán y alimentarán, por ejemplo un paso a producción más largo.

No entro a valorar en término cuantitativo qué es un ciclo corto o qué es un ciclo largo porque opiniones hay para todos los gustos, como también las hay para determinar si todas las iteraciones dentro de un proyecto deben tener la misma duración o no.

Si se quieren ciclos cortos y que estos sean efectivos (que sean resolutivos de cara a las expectativas del usuario) hay que disminuir la resistencia y eso no es una cuestión simple, sobre todo si se parte de la base de que se intenta aplicar este enfoque de desarrollo en proyectos que se encuentran en una etapa avanzada o que se encuentran en fase de mantenimiento.

Disminuir la resistencia debe ser siempre un objetivo a tener presente, sobre todo condiciona de manera grave el proceso de desarrollo. Si es importante en todos los casos, lo es todavía más cuando se pretende liberar nuevas versiones del producto cada poco tiempo.

Disminuir la resistencia implicará actuaciones no funcionales (y eso será necesario tenerlo en cuenta y explicarlo muy bien al usuario), como por ejemplo automatizar en lo posible la instalación de la aplicación en los diferentes entornos, la automatización en la ejecución de las pruebas partiendo desde las pruebas unitarias y subiendo cuantos niveles sean precisos, la realización de pruebas manuales en aquellos casos donde no llegue o no sea rentable automatización, la refactorización, etc…

También obligará a realizar diversas tareas de gestión para intentar agilizar los procesos y las actividades de las diferentes personas y roles que participan en el proceso de desarrollo y de implantación y aceptación del sistema.

Podemos invertir todo el esfuerzo del mundo en intentar que los usuarios puedan entender cómo se van a materializar las especificaciones que nos están indicando, sin embargo realmente no van a saber si el resultado satisface sus expectativas hasta que utilicen el software.

Esta circunstancia es otra característica más que apoya el enfoque iterativo e incremental en el desarrollo de software.

Hay una cita de Ben Schneiderman que resulta muy ilustrativa: “Una imagen vale más que mil palabras. Un interfaz vale más que mil imágenes”.

Que la naturaleza del desarrollo de software y su incertidumbre aconseje la aplicación de enfoques iterativos e incrementales no quiere decir que no se deba planificar, evaluar y controlar el trabajo que se hace, es más, es fundamental que estas actividades se realicen si se quiere llevar adelante el proyecto.

Pero, ¿es eso ágil? Puede serlo, como también puede no ser ágil no hacerlo. La agilidad es primero actitud, no lo olvidemos.

Cuando se desarrollo no se dispone de un presupuesto ilimitado, es más, desde mi punto de vista no es aconsejable (ley de Parkinson) tener un presupuesto excesivo (aunque sí holgado) sobre la base del trabajo previsto realizar (siempre habrá tiempo después de hacer ampliaciones si fuera necesario y estuviera justificado).

Por tanto, como es limitado se tiene que tener valorado lo que cuesta cada funcionalidad, requisito o historia de usuario que se quiera realizar y que los responsables funcionales aprueben de manera explícita cada uno de esos trabajos individuales con ese coste.

Es fundamental que eso se haga de esa manera, ya que siendo el feedback esencial para obtener un producto que satisfaga las expectativas del usuario, tiene un coste y el usuario debe ser consciente de él, para que sepa que la aproximación sucesiva al producto final tiene un coste y sus errores y falta de atención, también.

En todo este contexto, resulta esencial planificar, en primer lugar para que el desarrollo del software se realice con intención y se centre siempre en lo que resulte más prioritario e importante en cada momento y en segundo lugar para conocer cuándo va a estar disponible tal o cual funcionalidad o corregido tal o cual error.

Mi recomendación es que exista una planificación a alto nivel (bastaría con una priorización de dichas tareas, sin entrar en excesivo detalle) y que solo existiera una planificación detallada para las actuaciones a realizar a corto plazo. De lo contrario, el peso de mantener una planificación detallada más amplia requeriría un esfuerzo importante que habría que evaluar si compensa y si se disponen medios adecuados para tenerla actualizada.

Los proyectos de desarrollo de software tipo “llave en mano” son una fuente continua de fracasos, salvo excepciones (que las hay), se salvarán aquellos proyectos en los que se haya acertado en su valoración, hayan tenido una cierta estabilidad en el desarrollo (sin cambios significativos en procesos, interlocutores, etc…) y en los que tanto cliente como proveedor hayan estado acertados y hayan colaborado en la consecución de un objetivo común que no es otro que desarrollar un sistema que satisfaga las expectativas de los usuarios.

Sin embargo, lo normal es que estos proyectos no vayan bien y terminen por dejar descontentos sobre todo al cliente, pero también dejarán descontentos a muchos proveedores, de los cuales algunos se sentirán así por no haber cumplido con las expectativas del cliente y otros porque el proyecto han tenido pérdidas (como he dicho en numerosas ocasiones, desgraciadamente un número significativo de proveedores les da igual el cliente y solo miran los números).

En este artículo no analizo quién es el principal culpable del fracaso (entre otras cosas porque eso es algo que habría que analizar caso a caso) sino en señalar como una de las principales causas el enfoque de proyecto llave en mano en el que se espera que a partir de una previsión inicial de coste, se haya acertado en la misma y que todo en el proyecto haya discurrido con normalidad para alcanzar los objetivos marcados.

Cuanto más grande sea el proyecto, más probabilidad existirá de que el coste estimado sea erróneo y que existan contingencias en el desarrollo que provoquen desviaciones.

Hay que tener en cuenta que un proyecto llave en mano el proveedor está vendido si el cliente así lo quiere, pero también lo está el responsable técnico del cliente ante sus usuarios. ¿Por qué está vendido? Porque si no se gestiona adecuadamente los costes de los cambios de especificaciones en el desarrollo, al final todo quedará en un montón de actas de reuniones, correos y conversaciones que no son más que papel mojado y palabras que no valen para nada.

¿Solución? Enfoque iterativo incremental con valoración y priorización de los diversos requisitos bajo un marco de actitud ágil.

El feedback y tener capacidad para dar respuesta rápida al mismo es esencial, como también lo es dividir el desarrollo del sistema en incrementos donde la capacidad de error en las previsiones se minimice. Por otro lado, se debe establecer un mecanismo en el que los usuarios sean conscientes del coste del cambio y hacerse responsables de ellos y en el que los proveedores se responsabilicen de su trabajo y se centren más en el producto y en el cliente que en salvar los números del proyecto.

Existen diferentes formas de implementar este tipo de solución, podéis tener más información en la serie de artículos que dediqué a la contratación ágil:

Contratación ágil I
Contratación ágil II
Contratación ágil III
Contratación ágil IV
Contratación ágil V

Poner en producción y de golpe un sistema de información de un tamaño medio/alto puede provocar una situación de crisis que acabe con el propio sistema.

A la oposición inicial que tendrá la nueva herramienta por el simple hecho de modificar hábitos ya adquiridos se le suma que, salvo que se haya acertado muy mucho en la fase de análisis, el proceso o procesos que se informatizan hayan permanecido estables y se tenga muy controlada la aplicación de los procesos entre quiénes trabajan en los mismos (algo que se complica cuanto más descentralizada es una organización), se empezarán a solicitar cambios de todo tipo en el sistema y probablemente se dispongan de pocos medios para ejecutarlos ya que el esfuerzo se habrá centrado en el desarrollo del producto.

En esta situación los usuarios empezarán a decir que el sistema no se ajusta a sus necesidades y se quejarán de que el tiempo de respuesta para realizar dichos cambios es muy alto, ejerciendo presión a sus superiores indicando que la disminución de su rendimiento y productividad es debida al sistema de información.

No entro a valorar el comportamiento de los usuarios ya que en cada caso su intención puede ser diferente, lo que sí entro a valorar es que resulta complicado dar una respuesta cuando se tiene que actuar sobre un sistema grande y no se disponen de los medios adecuados para llevar diversas líneas de trabajo en paralelo.

Por este motivo el enfoque iterativo incremental no solo me parece la respuesta más natural a las problemáticas del proceso de desarrollo, sino que también resulta la solución más adecuada a la hora de realizar la puesta en marcha de un nuevo sistema, ya que se encontrará acotado el posible marco de actuación a los diferentes módulos que se vayan liberando de manera que se puedan centrar los esfuerzos en ir mejorándolos o corrigiéndolos en base al feedback del usuario y de esta forma no tenemos que estar intentando sofocar más fuegos que los que realmente podemos tratar.

Uno de los problemas de empezar a programar demasiado pronto es que en muchos casos no se ha llegado a comprender el problema de fondo que pretende resolver una determinada funcionalidad o módulo, en otros no se ha llegado a entender el proceso que se quiere informatizar y en otros, además de lo anterior, no se termina siquiera de asimilar qué es lo que quiere el usuario.

Es cierto que si planteamos un desarrollo iterativo incremental siempre tendremos la oportunidad de ir aprendiendo y de a partir del feedback del usuario ir acercándonos cada vez más a una solución que satisfaga sus expectativas, sin embargo si queremos optimizar los costes y tiempos de desarrollo, así como la deuda técnica, tenemos que intentar que el porcentaje de acierto en cada iteración sea adecuado a las características del sistema que se va a desarrollar.

En la línea de la cita de Cem Kaner que publiqué hace unos días, Milt Bryce comenta lo siguiente: “Ninguna cantidad de programación o tecnología elegante resolverá un problema que no esté adecuadamente especificado o no sea suficientemente comprendido”.

Uno de las principales ventajas de aplicar un enfoque iterativo incremental, además de permitir una mejor adaptación al cambio y de obtener el feedback del usuario desde etapas muy tempranas del desarrollo del producto, es que si está bien orientado, el desarrollo se basará en una priorización de las funcionalidades del sistema.

No se trata tanto de tener claro desde un principio todo lo que debe hacer el sistema como de tener claro qué es lo que resulta esencial para el mismo, ya que es por ahí por donde se debe empezar, evitando de esta forma distraer esfuerzos en módulos o funcionalidades accesorias.

Ahora bien, con la priorización no resolvemos del todo el problema ya que las actuaciones deben regirse por un principio de simplicidad: “la mejor solución es aquella que satisfaciendo las expectativas del usuario sea la más simple”.

Una ejecución compleja de un módulo o de una funcionalidad además de aportar un valor más que dudoso al usuario implica la realización de un esfuerzo adicional (a la par de una mayor deuda técnica) que perfectamente podría haber sido aplicado en un testing de más calidad del desarrollo, en un desarrollo de más calidad o en remanente para el desarrollo de módulos o funcionalidades menos prioritarias.

Sobre la productividad y simplicidad en el desarrollo, Milt Bryce realizó la siguiente cita: “No hay nada más improductivo que construir algo de manera eficiente que no debería haber sido construido”.

Seguir

Get every new post delivered to your Inbox.

Únete a otros 1.342 seguidores