archivo

Archivo de la etiqueta: iteración

La intención es la realización de acciones como resultado de una reflexión previa basada en hechos objetivos que pretende mejorar el producto (incrementar su valor) en cada iteración.

Conforme nos salimos de esta definición más nos acercamos al extremo opuesto, la prueba y error (no necesariamente malo porque habrá circunstancias donde se tenga que optar por esa estrategia).

La intención, por tanto, es tomar decisiones con una cierta base y si se acierta con ellas el ratio valor/número de iteraciones crecerá.

La intención se nutre del feedback, de nuestro background profesional y de nuestra interpretación del contexto actual y de su posible evolución.

La intención no supone conocer de antemano el éxito o el fracaso de la aplicación de las acciones, ya que de lo contrario estaríamos hablando de certezas, pero sí supone tratar de jugar con las mejores cartas ya que así existirán más posibilidades de acertar.

No contamos con presupuestos ilimitados y se quieren resultados acordes a la inversión realizada, más pronto que tarde, si no se desarrolla con intención, empezará a no existir un equilibrio entre coste y consecución de objetivos, conforme la distancia entre ambos se haga más grande más posibilidad hay de que existan conflictos entre usuarios y desarrolladores, entre cliente y proveedores, los cuales, a su vez crean resistencias que complicarán más, si cabe, el proyecto.

La iteración favorece la evolución del producto. Mediante el feedback tratamos de aproximarnos cada vez más a la solución que satisfaga las expectativas del usuario, por tanto, en cada iteración se le trata de dar un mayor valor al producto.

En un enfoque clásico o predictivo el feedback se obtiene principalmente en la fase de análisis cuando el producto sigue siendo una idea abstracta en la que se pueden imaginar sus formas pero donde la mayor parte del mismo está cubierto por niebla. Después se pueden realizar ajustes, claro que sí, pero no con agilidad ya que en este tipo de enfoques tiene especial importancia el cumplimiento de la agenda establecida: costes y plazos.

El feedback continuo favorece la evolución del producto de manera que teóricamente en cada iteración vamos adaptando las características del producto al contexto existente y a las expectativas que se tienen puestas en él. Cuanto más real sea el entorno en que se realiza el feedback, cuanto más cerca esté el usuario del producto con mayor intención se realizará la siguiente iteración y más efectivo será el resultado.

Es razonable pensar, por tanto, que en un contexto de evolución rápida del producto existirán más posibilidades de que el mismo tenga éxito.

Hablo de posibilidades, la realidad es otra cosa porque el éxito no se consigue a través del proceso (en este caso iteraciones más o menos frecuentes) sino a través de la correcta y adecuada ejecución de las acciones en el proyecto.

Si se fija al final del sprint una demo o una entrega es necesario dedicar tiempo al testing cuando se hayan finalizado las tareas fijadas en la iteración (previamente los mismos desarrolladores han debido probar el código que han hecho y si hay equipo de testing han debido colaborar en esas tareas conforme se va trabajando) además de otras tareas como puede ser la propia preparación de la entrega (si hay paso a producción o si la instalación en un entorno de demo lo hace un equipo distinto).

Esto quiere decir que la fecha final de los trabajos de desarrollo en la iteración debe ser anterior a la fecha de finalización del sprint. Otra posibilidad es considerar esas tareas de testing como una actividad más dentro de la pila de sprint. El tiempo que se debe dedicar a esta actividad no debe ser exclusivamente el necesario para hacer el testing sino que hay que prever un tiempo para corregir incidencias, ese tiempo lo determinará el equipo en función de la deuda técnica, de la complejidad de las funcionalidades desarrolladas en el sprint y del estado actual del equipo de proyecto (si ha habido cambios en el equipo existirán más posibilidades de que se hayan producido incidencias).

En cualquiera de los dos casos se reduce la cantidad de trabajo que se puede abordar en la iteración pero siempre será mejor eso que entregar software deficiente porque supondrá una resistencia para la próxima (o próximas) iteraciones.

Como desarrolladores somos reacios a la realización de cambios y no es que seamos así genéticamente sino por el hecho de que se nos ha formado y después hemos trabajado en proyectos en donde nuestra capacidad de ser flexibles estaba muy limitada por el cumplimiento de una agenda de costes y plazos (mucho más lo primero que lo segundo).

Cuando se enfoca un proyecto con presupuestos inmovilistas y sobre todo, carentes de toda aproximación a la realidad no se puede pretender que acojamos los cambios dando aplausos porque lo que el presupuesto no cubre (hasta cierto límite, claro está) lo tendremos que cubrir con nuestro trabajo.

No se trata de trabajar con presupuestos ilimitados, sino de desarrollar con intención (que es lo mismo que tratar de desarrollar de manera eficiente) y de determinar cuándo el valor del producto es suficiente y cuándo deja de ser rentable el crecimiento del valor con respecto a la inversión que se está realizando.

Con esta visión del desarrollo del software el cambio resulta bienvenido ya que se entiende que a través de él se consigue dotar al producto de un mayor valor (como consecuencia de que cada vez se ajustará más al contexto existente y a las expectativas de los usuarios).

Ahora bien, el cambio debe hacerse con intención (evitando en lo posible las circunstancias de prueba y error) y con un sistema en los que los cambios se puedan realizar con agilidad (deuda técnica acorde a las características del sistema que se desarrolla, arquitectura y modelo de datos escalable, etc…).

Cuando uno se acostumbra a este esquema de trabajo se acepta el cambio como una parte más del proceso de desarrollo de software y efectivamente se cumple la siguiente reflexión de Ken Auer y Roy Miller: “La única manera de deshacerte de tu miedo a los cambios en el código es hacerlos una y otra vez”.

Si se orienta el desarrollo a sprints (hay que tener en cuenta que el enfoque iterativo incremental es en sí un concepto más amplio) es, entre otros motivos, para conseguir un ritmo sostenible en el desarrollo.

Por eso cada sprint requiere tener preparada de antemano la materia prima, es decir, todos los inputs que necesita para poder ser completado, de lo contrario se tendrá que invertir tiempo en él para obtener esa materia prima, con el riesgo de producirse bloqueos por falta de esas entradas, lo que lo hará menos productivo y menos predecible en cuanto al cumplimiento de los compromisos.

Nos quejamos muchas veces y con razón de la falta de medios económicos para llevar a cabo el proyecto (acorde a las expectativas puestas en él y los plazos) y también de la falta de colaboración del área usuaria. Sobre esto último pocas veces nos paramos a pensar en los motivos que hacen que los usuarios no colaboren.

Uno de ellos puede ser precisamente la falta de medios para proporcionarnos la información y entregables que, una vez interpretados, conforman la materia prima de cada sprint. Es decir, muchas veces el product owner quiere pero no puede.

Se sobreentiende que quien contrata el trabajo ha tenido en cuenta esa carga de trabajo adicional (que en función del tipo de proyecto puede ser muy grande para las personas implicadas), sin embargo no es lo normal, ya que se piensa que con apoyos puntuales es suficiente, creyendo que el equipo de proyecto puede con todo y no, no puede, y si me apuráis, no debe, porque la carga de especificación del sistema debe recaer en el área usuaria.

Las consecuencias de esto es que determinadas tareas del sprint no estarán lo suficientemente definidas y eso hace mucho daño a esta dinámica de trabajo, tanto que nos deberíamos plantear, probablemente, objetivos menos ambiciosos.

Os indico a continuación algunas alternativas y aunque soy de la opinión de intentar reconducir la situación, no siempre va a ser posible:

– Adecuar la capacidad del equipo de proyecto a la carga del área usuaria. De nada vale tener una maquinaria capaz de producir x productos al día si solo entra material para producir x/4 productos.

– Plantear un enfoque iterativo incremental con fases de definición (con el nivel de detalle suficiente para el proyecto y la iteración) entre sprints. En este caso es más impredecible la duración de la fase de análisis pero más predecible la construcción.

– No plantear sprints propiamente dichos y aplicar estrategias de gestión del flujo de trabajo y del WIP (Work in progress), como por ejemplo, definiendo límites en el número de elementos terminados y no pasados a producción o dejando ese aspecto abierto y limitando el número de tareas en fase de análisis.

Cuando se falla en las estimaciones estamos golpeando en la línea de flotación del proyecto y también contra nosotros mismos. Se falla muy a menudo y después toca sufrir las consecuencias porque se adquieren compromisos que costarán muchísimo esfuerzo ser respetados.

¿Por qué nos equivocamos en las estimaciones? Son muchos los factores que pueden influir:

– La incertidumbre inherente que tienen los proyectos de desarrollo de software. Si aplicamos un enfoque iterativo incremental con sprints cortos tiene una menor o nula influencia dentro de ese segmento de trabajo, pero si consideramos el proyecto en su totalidad sí que la tiene cuando hay cambios significativos ya sea sobre las condiciones iniciales o sobre el producto que se lleva desarrollado.

– Se tiende a estimar considerando situaciones ideales y después sabemos que hay problemas.

– Se estima en muchos casos sin conocer suficiente detalle sobre el trabajo a realizar.

– Se estima en muchos casos sin conocer suficientemente las restricciones de la tecnología o del entorno de trabajo.

– No estima quien va a realizar el trabajo.

– La presión del cliente por tener plazos más cortos (y a menor coste).

Estoy seguro de que se os ocurren otro montón de causas que provocan que no se acierte con las estimaciones. Ahora bien, una cosa es que sea difícil estimar y otra que no se intente acertar en lo posible con las mismas porque no queda otra, por ese motivo es importante tomar el control de todos aquellos factores que estén en nuestra mano y que puedan afectar a la calidad de la estimación, esto dependerá como no podría ser de otra forma del proyecto en sí y de su contexto.

Como sabemos los problemas que hay con las estimaciones y que es necesario dar la importancia que se merece al feedback sería recomendable que el cliente pensase más en términos de valor que de agenda, si bien, no resulta sencillo conseguir esas condiciones ya que se mostrarán, por términos generales, reacios a considerar que el presupuesto inicial puede variar después …

Si aplicamos las prácticas de Scrum de pila de sprint y que la misma no se debe modificar una vez definida e iniciados los trabajos nos encontramos ante una situación problemática si aparece una urgencia que es necesario tratarla a corto plazo.

Antes de nada lo que hay que hacer es analizar lo crítica que es la urgencia o lo que es lo mismo, ¿puede esperar a que terminemos el sprint y se pueda tratar en el siguiente?. Esto es importante porque no todo lo que parece urgente lo es realmente como para tener que romper una dinámica de trabajo.

Si efectivamente no puede esperar, tenemos que adaptarnos a esa circunstancia, ya que sería mucho más perjudicial no hacerlo. No sería ágil aferrarnos a la metodología.

¿Qué hacemos?

Hay diferentes alternativas y a priori ninguna tiene que ser necesariamente la mejor, ya que sería necesario conocer las circunstancias concretas del proyecto.

– Se anula el sprint y se inicia uno nuevo con esa tarea y las del anterior sprint que se consideren convenientes (como mínimo las que ya estén terminadas).

– Se intercambian tareas ya definidas en el sprint por la nueva tarea, teniendo en cuenta que el esfuerzo restante en las mismas debería ser mayor o igual que el de la misma tarea.

– Lo mismo pero considerando la nueva tarea fuera del sprint, es decir, se resta capacidad de la línea de trabajo para asignársela a la nueva tarea para pasar el cambio a producción cuanto antes.

– Similar al caso anterior pero realizada por una persona de fuera del equipo (esto solo funcionaría con tareas que no requirieran un conocimiento profundo de la arquitectura, tecnología o el negocio).

– Se incluye la nueva tarea y se alarga la fecha de finalización del sprint.

Y seguro que se os ocurren otras tantas. Y os digo lo de siempre, lo importante es el producto no la metodología.

Otra estrategia puede consistir en prever que este tipo de circunstancias se pueden producir en el proyecto, para ello os recomiendo leer los siguientes artículos:

Incidencias e iteraciones I.
Incidencias e iteraciones II.

Resulta muy tentador comenzar una primera iteración prácticamente desde que se ha dado el pistoletazo de salida al proyecto.

Depende del proyecto, efectivamente. Si se trata de un nuevo aporte económico a otro ya existente y el equipo ha permanecido más o menos estable (tanto por parte de los desarrolladores como de los usuarios) casi que se puede empezar desde el principio, salvo que la evolución a realizar requiera hacer una revisión de la visión que se tenía del producto hasta la fecha y de lo que se preveía que iba a ser su devenir.

Sin embargo, para nuevos desarrollos, para evoluciones significativas de un sistema o para cambios significativos en el equipo de personas que intervienen en el mismo, es necesario hacer una parada para construir una imagen mental de lo que se quiere y que se traducirá en entradas en la pila de producto (que luego se refinará y mejorará conforme vaya avanzando el desarrollo y todas las partes vayan aprendiendo más y más porque las ideas al materializarse y cobrar forma requerirán ajustes y sugerirán algunos cambios de enfoque).

Esta etapa se llama exploración en XP y me parece acertada su denominación, ya que además, contempla la posibilidad de evaluar la tecnología y productos a utilizar durante el proceso de desarrollo.

Ahora bien, esta etapa no debe eternizarse y no conviene traspasar la frontera entre lo que es saber qué es lo que se quiere y obtener un análisis de requisitos detallado (digo que no conviene porque cada proyecto es diferente y tenemos que estar abierto a excepciones) porque de lo contrario habremos invertido (probablemente) esfuerzo que no va a retornar en beneficios, ya que todos sabemos que en el momento en que el usuario empiece a ver producto construido empezará a modificar las bases establecidas.

Tener una visión del producto es otro factor más para desarrollar con intención ya que permite tanto por parte del usuario como por la nuestra tener en cuenta más factores y esto se consigue viendo el producto y los problemas desde una escala más amplia.

Recomiendo la lectura del artículo: Preparando el primer sprint.

Mi recomendación es que las historias de usuario estén desarrolladas antes del inicio del sprint, así como que tengamos disponibles todos aquellos inputs que necesitamos en el mismo (por ejemplo, si una de las actividades consiste en una carga de datos, se necesitará tener acceso a ese origen de datos, si necesitamos conocer un determinado dominio de datos, necesitaremos que nos lo indiquen, etc…).

¿Qué es tener la historia de usuario desarrollada? Saber qué es lo que hay que hacer.

¿Cuál es el nivel de detalle que se necesita? Lo mismo. El que te permita saber qué hay que hacer, y eso puede variar en función de cada historia de usuario. No se trata de una especificación detallada de requisitos, tampoco de casos de uso (ahora bien, si entiendes que lo tienes que hacer así o que la historia de usuario lo necesita, adelante), se trata de tener la suficiente información para hacer una buena estimación y para conocer si necesitas algún tipo de input (para de esta forma tenerlo antes de empezar).

¿Eso quiere decir que no hará falta comunicación con el responsable funcional durante el sprint? No. La comunicación es esencial, la base. Una cosa es saber lo que hay que hacer y otra conocer todos los detalles.

¿Cuándo se debería hacer esa tarea? Este refinamiento de la pila de producto (porque al conocer más detalle se puede precisar mejor el valor de la historia de usuario y, en consecuencia, su prioridad), se hace mientras se está ejecutando un sprint.

¿Mientras se ejecuta un sprint? Sí, lo que no quiere decir que esté contemplada en el sprint. Decides tú. Puedes dedicar capacidad dentro del sprint a realizar esta actividad o hacerlo como una actividad paralela. Personalmente me gusta más la segunda opción, si bien, es importante que quien o quiénes la hagan participen en el sprint (lo que se hace es detraer de la capacidad total del sprint un porcentaje de estas personas para dedicarlo a generar el detalle de las historias de usuario).

¿Y si no se tiene detallada una historia de usuario y se quiere incluir en el sprint? Se puede hacer, ¿por qué no?, lo mismo la historia es tan simple que con su propia descripción ya se entiende qué es lo que hay que hacer (esto sucederá, sobre todo, cuando ya se tiene el producto bastante maduro).

Pero tampoco es necesario que la historia sea sencilla, también se puede hacer con otras más complejas, teniendo en cuenta que será más complicado acertar en la estimación, lo que puede afectar, si nos equivocamos, al cumplimiento de compromisos en el sprint.

Y no solo eso, al no tener la historia de usuario detallada, estamos dependiendo de que el responsable funcional pueda dedicarnos el tiempo que necesitamos para obtener la información que necesitamos o para que nos generen los inputs necesarios. Esto nos puede romper la producción y no solo afectar al desarrollo de esta historia, sino de otras que también formen parte del sprint.

Nos encontramos con la siguiente situación: tenemos un sprint en el que es necesario modificar una funcionalidad crítica del sistema (motivada, por ejemplo, por un cambio normativo) y se tiene que hacer de una vez (no podemos dividirla en historias más simples) ya que si no se ejecuta de esa manera no va a funcionar cuando la pasemos a producción.

En ese sprint, además, hay otras historias de usuario que se están desarrollando y en un equipo en paralelo tenemos a personas solucionando incidencias, cuya entrega se iba a sincronizar con el sprint. En un determinado momento, nos damos cuenta de que no vamos a tener la funcionalidad lista para la fecha de finalización del sprint, ¿qué hacemos?.

Hay diferentes posibilidades. La solución a aplicar podría ser diferentes en cada proyecto:

– Lo más tentador es retrasar la fecha de finalización del sprint. A mi personalmente no me gusta y creo que solo se debería hacer en el caso de que no hubiera otra salida. ¿Por qué? Creamos un precedente y más pronto que tarde nos volveremos a encontrar con una nueva situación, en este caso con menos criticidad, en la que se termine aplicando la misma solución y se entra de esta manera en un bucle nada beneficioso.

– Reducir el alcance del sprint, centrando los esfuerzos en la funcionalidad crítica. Podría funcionar si se detecta pronto la desviación y si el fallo en la estimación del esfuerzo de construcción de la funcionalidad crítica no es muy sensible. Si se aplica esta estrategia habrá historias de usuario comprometidas que no se podrán completar.

– Incrementar la capacidad del equipo. Esto solo va a funcionar si las personas que se incluyen en el equipo conocen la tecnología, las dinámicas de trabajo o si las tareas a realizar no requieren ese nivel de especialización. Podría valer con incrementar la dedicación de personas que no estén a tiempo completo en el proyecto o pasar personas del equipo de resolución de incidencias al equipo del sprint. Esta estrategia podría combinarse con la anterior.

– Completar la funcionalidad crítica en el siguiente sprint, es decir, el sprint termina con las historias de usuario que se hayan podido completar y en el nuevo sprint se sigue trabajando con ella.

La decisión a adoptar debe contar con el consenso del responsable funcional porque afecta a los plazos en que determinadas funcionalidades se incorporan, modifican o corrigen en el sistema, también es importante mantener la calma con el objeto de aplicar la solución más adecuada. En la retrospectiva es fundamental que se analice en qué se ha fallado y se tomen las medidas oportunas para reducir la probabilidad de que este problema se vuelva a producir en un futuro.