Archivo

Archivo de la etiqueta: ciclo de vida iterativo incremental

Uno de los motivos que dan lugar a deficiencias funcionales, problemas de integración, numerosos bugs, etc… es que los desarrolladores damos demasiadas cosas por supuestas.

También es un mal de los responsables funcionales pero debemos tener en cuenta que somos nosotros los que mandamos sobre nuestra cocina y por tanto, decidimos si tenemos suficientes ingredientes o no para poder elaborar nuestros platos. Otra cosa bien distinta es que nos “obliguen” a cocinar sin la materia prima necesaria, quienes toman esa responsabilidad deben saber que difícilmente de esta forma saldrá el plato esperado.

¿Por qué se dan por supuestas tantas cosas?

- Falta de comunicación. Es el principal motivo. Nos da pereza y/o pudor tener que estar consultando cosas, incluso en determinados momentos de manera continua. Tenemos que intentar evitar esas sensaciones, nuestro objetivo debe ser contar con toda la información necesaria para poder realizar nuestro trabajo con intención y de manera efectiva. No debemos cubrir los huecos que dejen los usuarios o nuestros compañeros salvo que sean cosas evidentes.

En el ámbito del equipo de desarrollo, las reuniones de tipo Daily Scrum ayudan mucho, si no lo has puesto en marcha, prueba y verás como mejora la comunicación del equipo; si ya la has puesto en práctica y piensas que no te funcionó, ¿realmente has llegado a obtener mejores resultados no aplicándola?.

En el desarrollo iterativo incremental la comunicación entre desarrolladores y responsables funcionales es intensa y es uno de los beneficios más importantes que aporta este enfoque. No solo obtenemos feedback en las demos o en las retrospectivas, no solo se revisan las prioridades en la preparación de la pila de sprint, sino que la comunicación debe ser frecuente para ir preparando el siguiente sprint mientras se desarrolla el actual (lo que se suele denominar refinamiento de la pila de producto).

No pongas muros, tíralos. La comunicación es esencial en el desarrollo de software.

- No rematar. Este es otro de los grandes problemas que tenemos los desarrolladores y uno de los aspectos que marca la diferencia entre un buen desarrollador y un gran desarrollador. ¿En qué consiste? Tendemos a relajarnos cuando estamos a punto de conseguir el objetivo, en ese intervalo entre el casi y el completo no se termina de hacer el esfuerzo final y se terminan dando por supuestas demasiadas cosas.

Existe una infinidad de caminos que pueden dar lugar al producto final. Solo algunos de ellos permitirán conseguir uno que tenga éxito.

Recorrer cada camino tiene un coste y cada uno de ellos tiene un coste diferente.

Por tanto lo ideal es encontrar el camino que permitiéndote conseguir un producto final de éxito tenga el menor coste posible.

Eso es un ideal pero no olvidemos que lo realmente importante es el valor del producto y en consecuencia su capacidad de amortizar la inversión.

Como desarrolladores tenemos la obligación de tener la mente abierta, de pensar que existen más soluciones que la que tenemos en la cabeza y que la más adecuada lo mismo te la proporciona quien menos te lo esperas. En un proyecto no gana quien consigue llevar más soluciones al producto final sino quienes tienen toman la decisión de sumar para que el proyecto tenga éxito. No se trata de una carrera de egos sino de un trabajo en equipo.

En un desarrollo iterativo incremental, el resultado de la iteración muestra una solución concreta que puede ser buena o mala, que puede ser mejorable o no, pero es la que es. En base a la misma se puede tomar la decisión de seguir evolucionando el producto o realizar modificaciones sobre la misma. No hay nada que deba ser inamovible si nuestro objetivo es el valor del producto final (dentro de las restricciones con las que tengamos que convivir en el proyecto).

Mary y Tom Poppendieck realizan la siguiente reflexión sobre este tema: ” Ua iteración debería ser considerada como una demostración de una posible solución y no ser considerada como la única solución”.

Trabajamos para eso, para desarrollar software que funciona. Pero, ¿de qué se trata eso de que el software funcione?. Cada uno tenemos diferentes perspectivas de las cosas, esta no iba a ser una excepción, por lo que para cada uno el listón puede estar a diferente altura y no necesariamente (dependerá del momento del proyecto, del contexto, de las características del sistema de información, etc…) unos tienen que estar siempre equivocados y otros estar en lo cierto.

Siguiendo un enfoque iterativo incremental vamos a ir liberando diferentes versiones del producto hasta obtener una “versión final” (lo pongo entre comillas porque el software es generalmente objeto de una continua evolución por lo que se puede hablar de versiones finalistas de un proyecto más que versiones finales de un sistema de información).

Independientemente de que desde el primer momento intentemos liberar el mejor software posible (desarrollo con intención) es razonable pensar que en las primeras iteraciones de una aplicación el listón no esté tan alto, sobre todo en aquellos casos donde esas iteraciones no llegan a un entorno de producción o de llegar su uso está limitado a su evaluación y porque la incertidumbre y falta de acoplamiento (al proyecto y entre las personas) en los momentos iniciales hace que se falle más de la cuenta (desarrolladores y usuarios).

No se trata de relajarnos en las primeras iteraciones, no quiero decir eso, sino de entender que no todos los momentos del proyecto son iguales (ni todas las circunstancias). No hay minutos prescindibles en un proyecto porque lo perdido no se recupera y por ese motivo siempre soy partidario de ir con intención siempre sin olvidar y, eso es lo que quiero dejar patente, que como en toda carrera de larga distancia hay que saber regular (y que todas las carreras son diferentes).

Un software que funciona debe satisfacer las expectativas del usuario. Si no satisface sus expectativas tenemos un producto que hace cosas pero no tal y como las quiere el usuario. No se trata de términos absolutos sino que tenemos que tener en cuenta los umbrales, es decir, la liberación de una nueva versión puede que no deje totalmente satisfecho al usuario pero sí supere sus umbrales de satisfacción. Nuestro objetivo será que la “versión final” esté más cerca de la total satisfacción del usuario que de su umbral superior pero eso requerirá mucho trabajo, voluntad por parte de los usuarios para darnos su feedback y diferentes evoluciones del sistema.

Un software que funciona no debe quedarse solo con la parte visible del iceberg. La deuda técnica cuenta y mucho. El usuario no la ve, no la valorará y sin embargo condicionará la mantenibilidad del producto y la disponibilidad del sistema ante futuras evoluciones del mismo. Es posible que haya clientes que no la tengan en cuenta, en cualquier caso soy de la opinión de que los proveedores deben marcar unos estándares de calidad para los sistemas que desarrollan, como elemento diferencial respecto a los que no lo hacen.

Más allá de la deuda técnica se encuentra la mantenibilidad (un concepto más general). Un software que funciona debe ser lo más fácilmente de mantener posible (dentro del contexto en el que se ha realizado el proyecto) y eso va más allá de la deuda técnica pudiendo contemplar elementos documentales si así fuera preciso.

Un software que funciona debe tener también en cuenta aspectos no funcionales. Algunos de ellos están en la parte visible del iceberg (aunque tal vez en la parte de atrás, la que no se ve a simple vista o la que requiere más tiempo para ser descubierta) como por ejemplo el rendimiento o la disponibilidad y otros en la parte no visible como por ejemplo la seguridad.

En el artículo de ayer vimos diversas formas de gestionar las solicitudes de modificaciones sobre la pila de sprint en donde no se aceptaban las mismas (inspiración Scrum) o en donde cabía la posibilidad de aceptarlas (inspiración Kanban siempre y cuando haya un orden). En cada una de esas estrategias el tiempo de espera cambia:

- Si nos inspiramos en Scrum el tiempo de espera medio para empezar a trabajar en nuevas tareas, será la mitad del tiempo de duración de los sprints.

- Si nos inspiramos en Kanban el tiempo de espera medio para empezar a trabajar en nuevas tareas será el tiempo que se tarda en que haya un hueco (Kanban establece límites en ciertas fases del flujo de trabajo), por lo que el tiempo de espera en este caso será mucho menor.

En ambos casos se tiene un control sobre la cantidad de trabajo en progreso (WIP: Work in progress) y eso es importante en cuanto a que estamos tratando de limitar el trabajo a la capacidad del equipo con el objetivo de conseguir predecibilidad y una mayor productividad pero, nada es gratis, es decir, se requiere pagar un precio que es el tiempo de espera.

¿Merece la pena pagarlo? Mi opinión es que sí ya que el caos no es productivo.

Se entiende que un equipo de proyecto irá incrementando la velocidad de desarrollo (volumen de trabajo que se puede afrontar en una iteración) hasta alcanzar una cierta estabilidad tras una serie de sprints (cambios en el equipo de proyecto ya sea de personas, en número, etc… afectarán a la velocidad, también cambios drásticos relacionados con el contexto de trabajo: tecnologías, entornos, metodologías, etc…).

Es bastante razonable que eso sea así salvo que la deuda técnica ofrezca cada vez una mayor resistencia.

Todo esto es teoría, si bien es la situación que se puede dar con mayor probabilidad.

Pero, ¿cómo medimos objetivamente el incremento de velocidad? Es decir, notaremos que el equipo puede afrontar una mayor cantidad de trabajo porque estimarán en menos tiempo el desarrollo o modificación de las pantallas, de la realización de informes, etc…, ¿pero cuánto realmente es esa mejora?, ¿en qué lo medimos?, ¿vale la pena el esfuerzo necesario para medirlo?.

Ahí estriba la dificultad porque lo ideal sería traducir los esfuerzos necesarios a una únidad genérica común, lo que en algunas metodologías se denominan puntos función, puntos por caso de uso, puntos por historia de usuario, etc… Esa traducción tiene un alto componente de subjetividad y se requerirá tiempo de perfeccionamiento conseguir una traducción con una cierta fiabilidad a esa unidad genérica común.

¿Invertimos esfuerzo en ello? Depende de en la fase en la que nos encontremos en la implantación de estrategias de desarrollo ágiles, si todavía no se tiene madurez (y para que exista se requiere tiempo) es mejor esperar a que se tenga una cierta estabilidad en la aplicación de estas dinámicas de trabajo de manera que el equipo tenga ya asimilados ciertos automatismos, una vez hecho eso, puede ser interesante empezar a medir.

No obstante, una cosa es medir en base a unidades genéricas y otra que no se haga un seguimiento de la velocidad en el sprint ya que resulta importante conocer (y eso se puede hacer con un esfuerzo mínimo) si el número de días de trabajo estimado para terminar los trabajos es congruente con la fecha de finalización del sprint por si fuera necesario (o posible) tomar alguna medida que permita reconducir desviaciones y/o gestionar las expectativas.

Se puede ver de esa manera pero es tan diferente el enfoque que ambos términos chirrían. Es cierto que cuando te planteas una iteración haces todas las actividades que sean necesarias sobre cada historia de usuario, no obstante la principal diferencia la tenemos en que al plantearse un desarrollo por incrementos, existe la posibilidad de realizar evaluaciones, sobre versiones en funcionamiento, desde el punto de vista del resultado (feedback) y de cómo se hacen las cosas (retrospectiva), las cuales permiten ir incrementando el valor del producto y adaptarse a los cambios que puedan producirse tanto desde el punto de vista del producto como de los métodos y organización del trabajo.

En un enfoque clásico o en cascada pueden existir revisiones intermedias del producto (más comunes) y también se puede obtener feedbacks y realizar retrospectivas (menos comunes), aplicar esas estrategias que podríamos considerar ágiles tienen sus ventajas, sin olvidar que siguen sin solucionar los principales inconveniente del desarrollo en cascada:

- El tiempo de puesta en marcha de versiones efectivas del producto.
- Su orientación al cumplimiento de una agenda: costes y plazos, lo que resta flexibilidad a la hora de realizar cambios sobre las especificaciones iniciales.

Existen requisitos que tardan en salir a la luz. A veces el usuario lo da por entendidos, en otros casos se da cuenta más tarde o bien se trata de ajustes sobre alguno de los ya especificados.

Es complicado traducir la imagen abstracta del sistema de información que el usuario tiene en la cabeza que en la mayoría de los casos está como cubierta con niebla y que solo se empieza a ver con claridad cuando nos aproximamos a ella (conforme el usuario tenga más claro el producto final con el que se va a encontrar).

Es importante sacar cuanto antes estos requisitos ocultos a la superficie porque a su vez pueden sacar a la luz otros requisitos ocultos y porque pueden tener importancia en el resultado final del producto. Para ello es importante aplicar enfoques iterativos incrementales para que en cada iteración el usuario esté más cerca del producto final y empiece a ver con mayor nitidez determinados aspectos del producto que está esperando así como aplicar otras estrategias o instrumentos como puede ser el prototipado.

Si el usuario no solicita cambios sobre las especificaciones iniciales es una señal de alarma ya que lo más probable es que no haya dedicado suficiente atención a la especificación de los requisitos, a la revisión de los mismos o a las diferentes iteraciones del producto que se están liberando. ¿Es posible que se haya acertado a la primera? Sí, es posible pero yo por si acaso pondría un intensa luz parpadeante de color rojo como alarma.

Siempre es posible desarrollar un software aplicando las mismas técnicas de gestión que para construir un puente, sin embargo estaríamos prescindiendo de una de sus principales características, su maleabilidad, lo que le permite adaptarse al cambio y modificar criterios con un coste asumible (siempre y cuando se tenga la deuda técnica bajo control).

Cuando tienes un puente a medio construir, tomar la decisión de poner un carril más en cada dirección puede ser prácticamente imposible o requerir una inversión muy superior a la que hubiera sido necesaria si se hubiera tenido en cuenta desde el principio.

En el desarrollo de software no es así. Es cierto que el cambio tiene un coste pero no es equiparable al de las construcciones físicas.

Renunciamos a la maleabilidad del software cuando lo importante es el cumplimiento de una agenda, es decir, se prioriza mantener previsiones de costes y plazos sobre la posibilidad de entregar un producto con mayor valor. Hay que analizar cada circunstancia y es posible que no haya otra alternativa que cumplir con la agenda: no es posible dedicar mayor presupuesto al proyecto y/o modificar los plazos, siempre y cuando se entienda que no es posible la cuadratura del círculo: cumplir agendas y tener al producto sometido a continuos cambios de criterio.

Mi apuesta es incrementar el valor del producto que se pone en producción y eso requiere un enfoque iterativo incremental para aprovechar el feedback del usuario. Esto tiene implicaciones presupuestarias que se solucionarían bien teniendo abierto el presupuesto del proyecto o si está cerrado centrarse en que las funcionalidades prioritarias vayan bien (esto último siempre y cuando no nos encontremos en una situación de Death March Project en la cual todo será mucho más complicado).

Yamamoto Tsunetomo fue un conocido samurai en la segunda mitad del S.XVII y las dos primeras décadas del S.XVIII. En su retiro, un joven samurai llamado Tashiro Tsuramoto transcribió las conversaciones que tuvo con él, dando lugar al Hagakure, en el que se describe por primera vez el código guerrero de los samurai.

Une reflexión sobre la intención que aparece en ese libro es la siguiente: “Si uno lanza sin vigor, siete de cada diez acciones no llegan a término”.

Me habéis leído escribir muchas veces sobre la intención, como el deseo real convertido en acciones fundamentadas que pretenden conseguir un objetivo. El fundamento de la acción viene dado por un análisis objetivo de la misma, tratando de reducir en lo posible actuaciones basadas en el prueba y error o sin suficiente conocimiento como para esperar que se obtengan los resultados esperados.

Precisamente es una de las causas principales de que un desarrollo iterativo incremental no sea efectivo, dando lugar a más iteraciones de las necesarias y a un mayor coste que si no se puede asumir puede dar lugar a que el proyecto fracase.

No se trata de tener toda la información, de tener completa seguridad de que la decisión que se toma es la correcta, porque pocas veces vamos a encontrarnos con esa situación de partida o tras un trabajo más o menos elaborado, sino de entender que tenemos más posibilidades de acertar si se han realizado las tareas y acciones oportunas que permitan elegir el camino más adecuado.

Ese es el desarrollo de la intención, antes hay que querer alcanzar el objetivo y estar dispuesto a invertir el esfuerzo que sea necesario, precisamente muchas de las decisiones que se toman en el transcurso de una reunión se quedan en nada, solo en palabras, debido a que parece que la energía se queda en la mesa una vez que todos (o por lo menos, los que tienen que desarrollar las acciones) se levantan de la mesa.

Cuando el sistema no tiene todavía demasiada entidad y los plazos son relativamente poco importantes se tiende en muchos casos a liberar pronto (buena práctica) pero sin tener excesivo cuidado con la arquitectura y el código.

Es cierto que se asocia esta dinámica al uso de metodologías ágiles pero no tiene nada que ver con el enfoque que se utilice, depende del desarrollador y de su capacidad de analizar las consecuencias de determinadas actuaciones a medio y largo plazo. De hecho con enfoques iterativos incrementales este tipo de problemas saldrán antes a la luz.

Si conforme va creciendo la aplicación se sigue en esa dinámica llegará un momento donde en lugar de tener la deuda técnica bajo control será ella quien te domine a ti.

Ese instante llegará y los costes y velocidad seguirán direcciones opuestas y cada puesta en producción será como una película de suspense por la elevada probabilidad de que se produzcan efectos colaterales.

La competencia es muy dura, si no eres capaz de dar un buen servicio los clientes buscarán otras opciones (imagina que un error en una nueva versión de un servicio que proporcionas a varios clientes les impide trabajar de manera adecuada una jornada entera de trabajo o les haces perder información), si hay un cambio de tendencia en el mercado y llegas tarde, será complicado volver a recuperar tu espacio.

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 1.718 seguidores