archivo

Archivo de la etiqueta: ciclo de vida en cascada

Ron Jeffries, Ann Anderson y Chet Hendrickson en el libro «Extreme Programming Installed» hacen la siguiente reflexión: «Si tu cliente sabe ahora exactamente lo que quiere, y si en el momento en que haya terminado todavía va a querer lo mismo, puede ser la primera vez en la historia del software que esto ha sucedido. Probablemente habrá un premio para ti en algún sitio».

Está bien que estos autores lo pongan en su libro pero probablemente tu propia experiencia te hará llegar a la misma conclusión.

La aparición de la agilidad y métodos de trabajo potencialmente ágiles (siempre os digo que realmente lo que la hacen ágil o no es la actitud de las personas en el proyecto) no fue un capricho, sino una respuesta a unos métodos de trabajo que no respondían a una realidad que se repetía de manera insistente en los proyectos de desarrollo de software y que se basaba generalmente en el ciclo de vida tradicional.

Pero las metodologías, marcos o estrategias de desarrollo son solo herramientas, es necesario entender el fundamento del enfoque iterativo incremental y se puede resumir perfectamente en la cita en la que se basa este artículo.

Los usuarios pueden tener claro lo que tienen (cosa que está por ver) e incluso que el contexto del proyecto se pueda mantener de forma más o menos estable y no influya excesivamente en la línea de desarrollo del producto pero lo más probable es que los usuarios vayan haciendo ajustes en su visión del producto conforme se trabaja con más detalle en el mismo y conforme van viendo versiones del producto mientras se está desarrollando o mientras se entregan sprints y eso es debido a que es muy difícil abstraer lo que se cree que se quiere, a algo concreto.

Si pese a que sois desarrolladores habéis sido usuarios (incluso vuestros propios usuarios) os habréis encontrado muy probablemente con situaciones en la que vuestra idea inicial del desarrollo ha sufrido cambios sensibles.

El enfoque clásico de desarrollo de software hace aguas en un entorno de incertidumbre como el que rodea a la mayoría de los proyectos. Me pide el cuerpo poner todos en lugar de mayoría porque la incertidumbre es inherente al desarrollo de software (desde mi perspectiva), otra cosa es que la misma pueda ser mayor o menor, materializarse sus riesgos asociados o no, sin embargo prefiero dejarlo así por no cerrar todas las posibilidades.

Y es que hacer predicciones partiendo de un conocimiento incompleto del problema y en un contexto que puede cambiar, incluso radicalmente, es muy complicado. No hay más que ver la gran cantidad de errores de estimación de esfuerzo y tiempo que se producen, incluso poniendo sobre la mesa la experiencia personal y un estudio previo del problema.

Como os he indicado en diversas ocasiones vengo de una formación clásica y de años trabajando con este enfoque y os puedo asegurar que no funciona. No quiero decir que sea imposible cumplir los objetivos, satisfacer las restricciones de plazo o de tiempo o satisfacer las expectativas del usuario, claro que es posible, generalmente con un gran desgaste de las personas implicadas en el proyecto porque las desviaciones no favorecen un clima de cordialidad y concordia. Sin embargo, lo habitual es que el proyecto y en consecuencia el producto se resienta.

Tal vez mi caso no sea muy representativo pero no hay más que mirar los resultados que se obtienen por regla general con este enfoque (no quiero decir que los otros enfoques sean infalibles) y seguro que no tienes que mirar muy lejos para hacerlo.

He mantenido muchísimas conversaciones con defensores de enfoques clásicos de desarrollo de software sobre este asunto y siempre es lo mismo, que se basan casi siempre en que no hay motivos por los cuales un sistema de software deba seguir una metodología o unos procesos diferentes que para construir un edificio y que no pensar eso es no creer en la ingeniería del software.

Prácticamente toda mi experiencia laboral se ha centrado en enfoques clásicos por lo que tengo criterio para tener una opinión totalmente contraria a eso. No hablo de teorías, hablo de realidades.

Y la realidad es que el software es flexible, es adaptable, es evolucionable y para que funcione tienes que programar hasta el más mínimo detalle. Un edificio no es flexible por lo que su posible adaptación (estructural) es mucho más compleja y costosa y no requiere tanto nivel de detalle para poder ser utilizado.

Precisamente por eso los procesos para la construcción son más rígidos y los cambios sobre las especificaciones iniciales son más por motivos técnicos que funcionales.

Si el software tiene esas características, ¿por qué ignorarlas?, ¿por qué aplicar un planteamiento predictivo (planos) cuando es posible aplicar un planteamiento evolutivo?, es más, ¿por qué utilizar un enfoque predictivo si la propia realidad del proyecto aconseja el incremento y la iteración?.

Para Ken Auer y Roy Miller: «Cuando se utiliza un proceso destinado a la construcción de cosas inflexibles como puentes para construir cosas flexibles como el software, no debe sorprender que más tarde el coste del cambio sea mayor».

Aunque resulte paradójico, la agenda es una de las principales causantes de la pérdida de control del proyecto porque en el momento en que se rompen sus premisas: estabilidad de las especificaciones, del contexto y acierto en las predicciones de coste y plazos y no se trata esta situación de manera natural ajustando la misma a la nueva realidad, estaremos trabajando en una condiciones fundamentadas en unas hipótesis erróneas y de esa situación no se puede esperar nada bueno.

La crisis del software se asoció al no cumplimiento de las agendas porque efectivamente los proyectos no cumplían objetivos de costes, plazos, alcance y calidad y a partir de ahí se constituyó la gestión predictiva de proyectos generando con las experiencias pasadas y con el paso del tiempo todo un cuerpo de conocimiento.

Precisamente este problema es el que sufren los desarrollos que siguen el enfoque clásico pero perfectamente son extrapolables a enfoques pretendidamente ágiles si los mismos están condicionados por agendas rígidas (digo pretendidamente porque agenda rígida y agilidad son conceptos contrapuestos).

Como es lógico, se mejoraron los resultados del pasado porque hay que tener en cuenta que se pasó del caos a un cierto orden, pero seguían sin ser satisfactorios a lo que había que sumar el desgaste que tiene este tipo de gestión entre todas las partes implicadas en el proyecto.

El culto a la agenda no es la solución porque pretende estabilidad y predicción en un contexto de incertidumbre que es inherente al desarrollo de software. Por eso, el centro no debe ser el triángulo de hierro sino el valor del producto de manera que costes, plazos y alcances supongan referencias y no límites.

Una de las claves para sacar adelante cualquier trabajo (y un proyecto no es más que un tipo de trabajo más), con su complejidad y sus características inherentes, es dividirlo en una serie de tareas que sean manejables: divide y vencerás.

El enfoque clásico o predictivo supuso el primer avance en ese sentido, si bien lo que hizo fue darle formalidad a lo que carecía de ella porque la división en tareas más simples en el desarrollo de software existe desde sus mismos inicios.

Esa división en procesos, actividades y tareas la podemos ver en Métrica v3, en versiones anteriores, en cualquier otra metodología basada en enfoques clásicos o en las propias definiciones genéricas de esa estrategia.

El inconveniente que se plantea es que divide en partes las actividades pero no el producto. Sobre esa aproximación inicial surgieron nuevas estrategias que tenían como objetivo descomponer el producto en partes y sobre cada una de ellas realizar una división de las actividades. Esto dio lugar a enfoques de tipo teórico como los desarrollos en espiral o más tangibles como los desarrollos iterativos incrementales.

Con este tipo de estrategias se puso en primer plano los conceptos de feedback y retrospectiva: conocimiento adquirido como consecuencia de la experiencia sobre versiones reales del producto (ya sea en producción o no) y la mejora continua de las prácticas y enfoque del proyecto.

El siguiente paso fue hacer que la descomposición del producto fuera en trozos más pequeños definiéndose para ello sprints de duración fija o variable pero que en cualquier caso iban a ser de corta duración. En este contexto el feedback y la retrospectiva ganan en intensidad, se realizan cada poco tiempo y el producto está preparado para adaptarse al cambio.

En esta evolución se ha pasado de la especificación del producto a su visión: se tiene una colección de tareas a realizar que se va modificando conforme avanza el proyecto y solo se estudian en detalle cuando se está preparando la siguiente iteración.

En los enfoques clásicos se trabaja en procesos en donde los entregables finales: catálogo de requisitos, análisis, diseño, construcción, etc… tratan sobre un producto completo, ¿existe sobreproducción?.

Si se entiende que se ha contratado el desarrollo de un software en base a unas especificaciones de partida (un alcance), un coste y unos plazos y que se ha decidido que la metodología de desarrollo sea esa, no deberíamos hablar de sobreproducción: se ha hecho lo que se ha contratado.

Otra cosa es que buena parte del trabajo realizado sea efectivo y no lo digo porque crea más o menos en este tipo de enfoques (que ya sabéis que no, pero sin cerrar la puerta a que en proyectos concretos sea la solución más válida), sino porque la propia naturaleza de los proyectos de desarrollo de software y nuestra propia experiencia nos demuestra que trabajar con la hipótesis de que los requisitos van a ser estables, es algo más utópico que real.

Esto quiere decir que si nos cambian requisitos (modificación, eliminación o adición) en cualquier momento (incluso haciéndolo bien y adaptando el alcance), se debería producir una modificación en cadena del conjunto de entregables y elementos de proceso.

¿Hay sobreproducción? Ya dije antes que desde una perspectiva a alto nivel no, pero si lo miramos a una escala de mayor detalle sí que hay un trabajo excedente que se ha realizado y que después lo mismo no se ejecuta o como consecuencia de modificaciones de otras funcionalidades también requiere cambios.

Desde este punto de vista un enfoque clásico se convierte en ineficiente conforme se van rompiendo las premisas iniciales de estabilidad.

Un enfoque iterativo incremental de ciclos cortos y el feedback que se obtiene a partir de ellos permite probar la efectividad de los enfoques de los usuarios (que inicialmente no son más que hipótesis sobre lo que quieren) y realizar ajustes que nos van acercando progresivamente a una solución que realmente satisface las expectativas del usuario.

En los enfoques clásicos las hipótesis no se compruebas hasta etapas finales del desarrollo en donde los presupuestos están casi agotados y en donde el tamaño del producto dificulta la realización de modificaciones. Menos dinero, más envergadura del producto, más deuda técnica, menos margen de maniobra.

Todos los que hemos trabajado con ciclos de vida en cascada y/o con contratos llave en mano hemos sufrido esa situación. Da igual lo bien que trates de hacer el análisis que siempre habrá funcionalidades que no se han definido correctamente, que ni siquiera se han definido o que son mejorables y, además, siempre existirán circunstancias a lo largo de la ejecución del proyecto que impliquen cambios de prioridades.

El conocimiento real del producto se va obteniendo conforme se va desarrollando, ¿por qué? pues porque se contrastan las hipótesis y con ello se va mejorando y adquiriendo nuevo conocimiento.

Está bien tener una visión de lo que se quiere pero el detalle se debe trabajar poco a poco, lo demás es correr un riesgo importante de desperdiciar esfuerzo y no nos podemos permitir ese lujo porque en el propio devenir del proyecto y del desarrollo del producto habrá esfuerzo que no proporcione un valor directo, ya que a veces la solución elegida para una determinada funcionalidad deberá cambiar de orientación o ser perfilada en diferentes iteraciones, algo que es normal en cualquier proyecto y que, por tanto, debe contar con suficiente respaldo presupuestario que, como no andará sobrado, es conveniente cuidarlo desde un principio.

Podemos discutir el porcentaje pero no el fondo de la siguiente reflexión de Larry Bernstein: «Sólo entre el 40 y 60% de los requisitos de un sistema se conoce al comienzo del proyecto. El resto emerge con el uso. Barry Boehm acuñó el término requisitos emergentes para describirlos”.

Y no se trata de requisitos que aparecen por arte de magia sino que son consecuencia de la evolución que existe entre lo que el usuario cree que quiere y lo que realmente necesita y de la separación que existe entre la visión abstracta de un producto y su implementación real.

De ese porcentaje inicial de requisitos previsibles, una parte importante de los mismos tiene a su vez que ser perfilada también con la utilización del sistema.

Esto al final nos hace ver que los desarrollos llave en mano y/o los ciclos de vida en cascada no se adaptan a esta realidad y por ese motivo no suelen ofrecer buenos resultados y si lo consiguen es porque todas las partes en alguna parte del proceso de desarrollo se dan cuenta de que es necesario llegar a un acuerdo para que el producto se dirija hacia lo que realmente se necesita y no hacia lo que inicialmente era previsible.

Te puedes esforzar en un proyecto para cumplir una planificación y ceñirte a unos costes y sin embargo no conseguir nada, incluso desarrollando todas y cada de las funcionalidades tal y cual se especificaron en un principio.

¿Por qué? La idea inicial no tiene por qué funcionar, de hecho todos sabemos que es muy difícil acertar a la primera y todavía más conforme se incrementa el tamaño y/o complejidad de la solución. Esto es extensible tanto para el desarrollo de un producto propio como para el desarrollo de software para terceros.

Por tanto, afirmar que un producto que va acorde a unos plazos, unos costes y unas determinadas funcionalidades va bien, es mucho suponer si no se mide realmente el valor que se está obteniendo, de ahí el riesgo que supone, por ejemplo, un desarrollo en cascada cuando los desarrolladores y usuarios viven separados desde la finalización del análisis hasta etapas próximas a la entrega.

En los desarrollos iterativos incrementales, con entregas más frecuentes y con versiones en producción desde etapas tempranas el feedback permite evaluar el valor real que se está obteniendo y adoptar decisiones encaminadas a incrementarlo.

Otra cosa, es que pese a trabajar de esta forma se quiera seguir con el guión inicial prácticamente sin variaciones, en ese caso, poco importará la metodología porque predominará el seguimiento de un plan y esto es consecuencia muchas veces no de confiar ciegamente en él, sino por el afan de cumplir, de cubrir el expediente: «si al final se fracasa, la culpa no es nuestra, sino del plan».

Parece políticamente incorrecto en el mundo ágil la utilización de la palabra requisito. También, aunque algo menos, la palabra especificación. El motivo principal es su asociación a los desarrollos en cascada y a un modelo de desarrollo basado, yéndonos a un extremo, al dicto, interpreto/apunto, construyo.

Parece que el concepto de historia de usuario se asocia más a la colaboración que es la base en la que se sustenta la agilidad y el enfoque de desarrollo iterativo incremental (os recuerdo que un enfoque o ciclo de vida concreto de desarrollo no es en esencia ágil ya que depende de la actitud con que se aborde).

Estoy de acuerdo en que en determinados momentos usar la palabra adecuada puede ser importante pero tampoco se pierde valor si el fondo realmente dice lo que queremos transmitir. Lo realmente importante, independientemente del nombre que le demos, es que en los ciclos de vida clásicos se piensa en el producto, por encima de analizar y trabajar sobre los problemas reales que se quieren resolver y esto es así, entre otras cosas, porque los desarrollos en cascada piensan en los productos en términos finalistas y en los enfoques evolutivos en términos de valor ganado en aproximaciones sucesivas hacia una determinada solución.