Feeds:
Entradas
Comentarios

Archive for the ‘Agile’ Category


Hola de nuevo a todos, el tema que voy a tratar en este post en su momento me ocasionó un shock acompañado de su posterior revelación (es que soy un tío simple e impresionable).

En el anterior post de esta serie comenté que había que valorar el coste de complicar nuestro diseño contra el tiempo disponible y los beneficios a largo plazo que nos iba a reportar. En el caso de un proyecto gestionado mediante el paradigma ágil, el equipo de desarrollo debe ser capaz de aceptar muchos cambios a un ritmo alto. Estos cambios provienen al menos de dos fuentes diferentes: cambios o malentendidos a nivel funcional, y otros ocasionados por tener que entregar funcionalidad de forma continua, lo que nos deja en la posición de tener que cambiar y extender nuestro diseño de forma interminable. Como conclusión tenemos que nuestro diseño debe ser barato y rápido de cambiar y que toda técnica orientada a este fin es valiosa.

¿Cómo podemos abaratar y agilizar los cambios en el software? ¿DRY, SOLID, OO, Modelo de dominio? Bueno, no vayamos tan rápido, centrémonos primero en lo esencial. Pensad un poco en la siguiente pregunta, ¿qué es lo que hacemos siempre (siempre) cada vez que tenemos que introducir un cambio en nuestro sistema? …. Pues es obvio, siempre hay que leer el código ya existente y entenderlo para empezar a saber como cambiarlo. ¿Cuántas veces os ha pasado que no entendéis el código que escribisteis hace dos meses? ¿Y el de la semana pasada? A mi me ha ocurrido de no entender código del día anterior, ¡ menuda bazofia ! Si no podéis entender vuestro código, imaginaros la comprensión que tendrán de éste vuestros compañeros cuando les toque mantenerlo o añadir un cambio.

Para hacer que vuestro código se pueda modificar de forma rápida y barata, es indispensable que sea legible y comprensible (dios, que shock, ¡ no voy a poder dormir !). Este principio es muy básico y para mi es el principio de “calidad mundana” más importante que existe. Un nombre popular para este principio es el de “código expresivo”. Es un principio tan esencial que aunque no seáis ágiles lo vais a necesitar. Tal vez no sea tan crucial para proyectos no ágiles, pero sí es muy importante en la fase de mantenimiento, ¿alguno ha mantenido aplicaciones ilegibles alguna vez? Seguro que sí. Quizás el ejemplo clásico de “no ágil” y necesidad de “código expresivo” sea el caso del mantenimiento de aplicaciones legacy. Cuando hay que mantener una base de código que es difícil de leer, a veces es más barato reescribirla desde cero.

Un escenario más confuso se produce con aplicaciones de “campaña”, de usar y tirar. La aplicación debe estar lista para una fecha (time to market crítico), se usará durante dos o tres meses, y después se desechará. En estas aplicaciones no va a haber mantenimiento evolutivo. En un entorno ágil vamos a seguir necesitando que el código sea expresivo, ya que los cambios llegarán seguro durante la fase de construcción. En un entorno no ágil no habrá cambios durante la fase de construcción (¿seguro?), gracias a un fabuloso contrato cerrado, con lo que alguno podrá pensar que no es necesario que el código sea legible, y que la necesidad de facilidad de cambio (calidad mundana) tiende a cero. A esas mentes preclaras les deseo que entreguen el software con cero defectos, porque como empiecen a llegar bugs en la fase de explotación, que para colmo dura unas pocas semanas o meses, no sé como los vas a resolver a un ritmo suficientemente rápido como para que los de negocio queden satisfechos. Por lo tanto la legibilidad del código no sólo es importante para aceptar el cambio (ser ágil), sino también para arreglar bugs. Como todo el software tiene bugs (escondidos tal vez), todo el software, ágil o no ágil, de “campaña” o “estratégico”, debe ser legible.

¿Qué técnicas nos pueden ayudar a conseguir este fin? Pues hay muchas:

  • Pair programming (programación por parejas). Sí, señor, no hay nada como un compañero leyendo por encima de tu hombro lo que escribes, tratando de entenderlo y buscándole defectos, como para que tu código de repente se vuelva legible (para los demás). Afortunadamente cuando cambie el turno te podrás vengar, je, je }:-)
  • Peer review (revisión de código). El pair programming no es más que revisión de código continuo, ¿por qué necesitamos otra etapa de revisión de código? Pues muy sencillo, a veces las parejas desarrollan un sentido de la identidad compartida, y un sentido de la legibilidad un poco particular. Para evitar esto es conveniente rotar las parejas, y también que otros compañeros, y deseablemente alguien un poco externo al proyecto (normalmente alguien respetado), revise el código. Por supuesto en la medida de lo posible y las restricciones de tiempo y dinero.
  • Domain Model (modelos de dominio). Consiste en modelar de forma explícita conceptos usados en el dominio del problema. De esta forma cuando veamos el código reconoceremos conceptos del problema directamente en el código, lo que nos ayudará a entender éste. Este enfoque es muy popular y tuvo como repercusión la aparición del paradigma OO, en el que aparece el concepto de objeto que nos permite modelar los conceptos de nuestro problema de forma directa, algo muy costoso de hacer con un lenguaje procedural.
  • Fluent API (API fluida o API sexy) o Internal DSL y también External DSL. Como ya comenté en un post anterior, los DSL nos permiten una mayor legibilidad, al modelar directamente el lenguaje de dominio de nuestro problema. Este problema puede ser la funcionalidad de negocio, pero también puede ser un problema técnico (procesamiento de XML, de BBDD, seguridad, etc). Notad que en los DSLs el énfasis está en el lenguaje y la dinámica del problema, mientras que en el modelo de dominio nos centramos en la estructura estática. Esto hace ambas que ambas técnicas sean complementarias unas de otras.

Como veis la mayoría de las técnicas de diseño ágil tienen como una de sus ventajas, si es que no su principal ventaja, el hacer el código más legible. Algunas son más potentes que otras, y también más costosas que otras. Como siempre la decisión debéis tomarla teniendo en cuenta el coste. Por ejemplo, construir un DSL, ya sea interno o externo, puede tener costes altos, sobre todo en algunas plataformas tecnológicas. Otras como TDD, Pair Programming o modelado de dominio puede tener algún beneficio adicional.

Por otro lado, para que lo penséis, ¿se os ocurre alguna técnica no ágil que facilite la legibilidad del código? ¿Wizards y generadores de código? ¿Copy&Paste? ¿DFD? ¿Alguna idea? Al fin y al cabo el paradigma no ágil también necesita que su código sea legible.

No lo he puesto en la lista anterior, pero algunos refactors pueden ayudarnos con la legibilidad de nuestro código. El problema es que esos mismos refactors en diferentes circunstancias nos hacen perderla. En general yo uso la cantidad de legibilidad que gana mi código como guía para saber si hacer el refactor merece la pena o no.

Finalmente, si usáis TDD, tenéis que tener en cuenta que la legibilidad del código no sólo se aplica al código de producción, sino también al código de test. Para mi, es incluso más importante que el código de test sea legible a que lo sea el de producción, ¿por qué? Simplemente porque el código de test define la API de vuestro sistema (o componente), son los ejemplos de uso. Si estos ejemplos (los tests) son legibles, ¡ habréis conseguido que vuestro código de test sea a la vez la documentación ! Nada de irse al javadoc, un buen vistazo a los escenarios de vuestros tests y un programador ya sabrá como manejar vuestro sistema (o componente). Por otra parte, una buena suite de pruebas, bien legible, y refactorizada adecuadamente, os proporciona además, un “fluent API” o “internal DSL”. O sea, que simplemente por hacer que vuestro TDD sea legible, obtenéis un DSL y una guía del programador (con how to’s), gratis de serie con vuestro sistema con pruebas automáticas. A mi esta idea me seduce bastante.

Por supuesto si no practicáis TDD todo esto os dará igual :-P —> ¡ A qué esperais para empezar con vuestro TDD ! ¡ Es que acaso pensáis que el TDD sirve para “probar” !

Un punto importante a tener en cuenta es la plataforma tecnológica en la que nos movemos. Por ejemplo, algunos lenguajes nos permiten hacer nuestro código más expresivo que otros. Comparad en este sentido JAVA o COBOL con Ruby, Scala, Groovy, etc. La mayoría de los lenguajes modernos van en la dirección de facilitar cada vez más que nuestro código sea legible. De hecho la evolución de los lenguajes de programación, desde el código máquina hasta el Groovy, han ido en esta dirección. Los desarrollos más recientes (o no tanto) que hacen que JAVA quede obsoleto en este sentido son:

  • Intentar eliminar al máximo el su ruido sintáctico. Declaraciones de tipos, palabras reservadas, tokens, etc. oscurecen la sintaxis de nuestro código, haciéndolo menos legible. Algunas técnicas usadas por los lenguajes para mejorar esta:
    1. Para los lenguajes de tipado estático, la inferencia de tipos, como demuestra Scala, nos evita tener que escribir un montón de código. El compilador es inteligente y en los casos en los que el tipo de una expresión sea computable en tiempo de compilación, nos permite omitir la declaración de tipo en las variables, parámetros y valores de retornos de las funciones. Esto es una de las razonas por las que el compilador de Scala es más lento que el de JAVA.
    2. Los lenguajes de tipado dinámico no necesitan estas declaraciones, con lo que son de forma natural más sucintos y expresivos. Esto, junto con el auge del TDD, hace que este tipo de lenguajes se haga cada vez más popular.
    3. Sintaxis flexible. Los lenguajes modernos permiten una sintaxis flexible. Podemos ahorrarnos llaves, comas, puntos, puntos y comas y paréntesis en algunas circunstancias. El resultado es un código con menos ruido sintáctico y más parecido al lenguaje natural, lo que ayuda al desarrollo de DSLs internos. Groovy, Ruby o Scala son ejemplos de lenguajes que usan esta técnica.
  • Paradigma mixto. La mezcla de paradigmas OO y Funcional nos permite usar el paradigma más expresivo según para que tarea. El uso de closures o bloques de código nos permite simplificar mucho nuestro código haciéndolo más legible.
  • Metaprogramación. La metaprogramación nos permite construir DSLs internos de forma más sencilla. En este sentido Groovy y Ruby son bastante potentes.

Si veis que vuestro lenguaje de programación os impide que vuestro código sea lo suficientemente expresivo como para cambiarlo con suficiente rapidez, empezad a pensar en adoptar otro lenguaje.

Como os dije soy un tío simple e impresionable. ¡ A pasarlo bien !

Read Full Post »


Hola a todos, como veo que hay mucha inquietud por todas esas prácticas de desarrollo ágil, como el TDD, el refactor y el pair programming, y como me huelo que por ahí que se ha puesto de moda eso del SOLID, he decidido hacer unos cuantos de posts sobre el diseño de software ágil. Espero que me salga algo coherente…

En posts anteriores he hablado mucho de gestión de proyectos, sobre todo de Scrum. Me centré en que lo bueno de las metodologías ágiles es que proponen que se debe entregar valor de forma continua y cuanto antes mejor. Ésto es mucho más sencillo de decir que de hacer. Scrum, por ejemplo, no nos orienta sobre cómo conseguir implementar en cada sprint rodajas de funcionalidad potencialmente entregables al usuario. De hecho esto es bastante complicado de hacer, ya que implica que con cada nueva funcionalidad que queramos implementar, debemos modificar o extender los componentes de software que hayamos realizado hasta el momento. Además es probable que debamos introducir nuevos componentes, no previstos hasta el momento, en la arquitectura del sistema y que estos encajen con los ya existentes. Todo un desafío. Las prácticas de ingeniería ágiles no son más que unas herramientas para conseguir estos objetivos. Muchas de dichas prácticas existen desde hace mucho tiempo (pre agilismo) dentro del paradigma OO, aunque hayan sidos ignoradas por nosotros, programadores de JABOL.

Antes de meterme en materia técnica, y abrir el arsenal de armas de destrucción masiva, voy a explicar en este post lo que quiero decir cuando en una consultoría digo: “pues depende…”. Es un tema que me preocupa porque empiezo a oír hablar de SOLID, código expresivo y demás, y todo ello justificado en nombre de una entidad abstracta llamada “calidad”. Es una corriente que me está dando algo de miedo, ya que en nombre de la “calidad”, me puedo tirar refactorizando mi código y chapándolo en oro por los siglos de los siglos sin entregar nunca a tiempo nada de valor a mi cliente. Me da la impresión de que algunos hablan de la “calidad” de la misma manera en la que un sacerdote podría hablar del “bien supremo” o un artista de la “belleza” de su obra. Las técnicas de diseño ágil son armas poderosas, y con ese poder viene la responsabilidad de no hacernos pajas mentales con ellas :-P

Mi postura es que la calidad del software, como entidad platónica y absoluta no existe. Es algo que no es medible, ¿alguien me puede proponer una fabulosa métrica que la mida y que sea factible de implementar? Si algo no es medible no debemos tomarlo como guía para tomar decisiones de diseño de nuestro código, por lo tanto, yo no uso la calidad para estos fines. Veamos pues como bajar al mundo real para tomar decisiones de diseño. En el mundo real del desarrollo de software profesional el objetivo es entregar software al cliente y que éste esté satisfecho con él. Por satisfecho quiero decir que se deben cumplir las dos siguientes condiciones:

  • El funcionamiento del software cumple las expectativas del cliente de forma razonable.
  • El software se entrega en un plazo de tiempo y con un coste razonable para el cliente. Si es más importante el coste o el tiempo lo debe decidir el cliente al principio del proyecto, de forma que podamos balancear estos dos factores adecuadamente.

O sea, que no descubro la pólvora, el cliente estará satisfecho si el software funciona, está a tiempo y su coste no se ha ido de madre. La parte quizás más problemática es la definición de “razonable”. Para mi el significado de razonable es algo que se debe acordar con el cliente mediante negociación, aunque eso sí, es una negociación asimétrica donde el cliente tiene la última palabra.

Por lo tanto el objetivo del diseño de software ágil es hacer software que funcione, respetando unas restricciones de tiempo y de dinero, y se entregue dicha funcionalidad de forma continua e incremental, aceptando posibles cambios. Las técnicas y principios de desarrollo ágil como TDD, Pair Programming, SOLID, KISS, DRY, etc. no son más que meras herramientas para conseguir ésto, no las confundamos con el objetivo. Antes de aplicar un patrón de diseño, o una refactorización, calculad el coste que os supondrá hacerlo en tiempo y dinero y comparadlo con el ahorro de coste y dinero que os supondrá a largo plazo. Si no hay un beneficio obvio, no lo hagáis. Así que cuando alguien me pregunta: “¿es bueno seguir los principios SOLID?”; y yo respondo: “pues depende..”; simplemente estoy diciendo que en función del contexto de tu proyecto tendrás que analizar si te va a dar beneficios o no.

En este sentido, la primera técnica que podemos aplicar es usar un timebox. Un timebox es un intervalo de tiempo predefinido, y no alterable, que restringe la implementación de una tarea. Ejemplos de timeboxes son: pomodoro, jornada de trabajo, sprint, deadline… La idea es que nos concentremos en cumplir con nuestras tareas y sintamos la presión de que se no acaba el tiempo. Esta presión nos ayudará a evitar que nos “entretengamos” en cosas que no sean conseguir terminar nuestra tarea. Usar timebox es una técnica común en el mundo ágil, ya que nos permite controlar nuestro ímpetu por demostrar como de bien sabemos programar, y centrarnos en simplemente implementar la funcionalidad, y si da tiempo se mejora su “calidad”. Usar timebox es una forma efectiva de conseguir KISS y YAGNI, si tienes claro que tienes un límite de tiempo vas a lo práctico, y haces lo más simple que puede funcionar y te olvidas de cosas que no vas a necesitar.

Enganchando con la primera parte de este post, el desafío técnico del agilismo, consiste por un lado en entregar incrementos de funcionalidad, y por otro aceptar cambios en la funcionalidad y el contexto del proyecto. Por lo tanto en un proyecto gestionado de forma ágil, vamos a estar continuamente cambiando nuestra arquitectura, nuestro diseño y los componentes ya existentes. Esto es así, aunque no cambien los requisitos funcionales, al tener que modificar el software ya existente para poder acomodar al menos la siguiente funcionalidad a entregar. Si hay cambios funcionales, el ritmo de cambio a absorber por nuestra arquitectura es mayor aun. Por lo tanto nuestro diseño y nuestros componentes deben ser maleables y flexibles. Cualquier técnica o principio de diseño, que recorte los gastos o el tiempo de implementar un cambio, rendirá beneficio en un proyecto ágil.

Por lo tanto ya tenemos una regla para guiarnos a la hora de tomar rápidamente decisiones de diseño. Podremos aplicar una técnica y/o refactorización, siempre y cuando:

  • Podamos aplicarla si no nos vamos a saltar el timebox de la tarea a implementar. Esto asegura que no tiene un coste alto, y no nos desvía de nuestro objetivo de hacer software que funcione.
  • Tenemos claro que consigue hacer que nuestro diseño sea más sencillo de cambiar en un futuro.

La regla anterior tiene una debilidad, la posibilidad de que el timebox sea irreal y demasiado corto para realizar la tarea. En este caso nunca tienes tiempo para refactorizar ya que estas un ritmo de trabajo insostenible, y tu diseño puede hacerse frágil ante el cambio. Por lo tanto tengo otra regla que tiene más precedencia que la anterior: si te cuesta cada vez más encajar una nueva funcionalidad en el diseño, refactoriza. Esta regla actúa como una alarma que me indica que debo “complicar” el diseño, sí o sí, ya que éste no es lo suficientemente flexible para aceptar cambios.

Resumiendo mi postura,la calidad del software no existe en si misma. Lo que realmente nos importa es terminar en tiempo y dinero con software que funcione. En un contexto ágil esto va a implicar que tu software debe ser maleable y aceptar cambios de forma rápida y barata. Olvídate de métricas, documentación y estándares. Céntrate en que tu software funcione y acepte cambios fácilmente. Me gusta llamar a esto calidad mundana del software, en contraste con la idea de que la calidad es un ideal a alcanzar como objetivo. Para obtener suficiente “calidad mundana”, pero nada más, recopilando lo dicho anteriormente, yo suelo usar las siguientes reglas:

  • Usar timebox para centrarme en implementar funcionalidad y no salirte de costes y tiempos. Puedo usar distintos timebox (pomodoros, jornadas y sprints) para distintos ámbitos (tareas, escenarios y Product Backlog Items). Esto promueve KISS.
  • Si sobra algo del timebox, cambia tu diseño para que admita cambios de forma más sencilla. En función del nivel del timebox puedes afrontar cambios más locales o más globales en diseño. Por ejemplo, en un pomodoro puedes intentar un refactor local, en un sprint, proponer a tu equipo alguna tarea de review de código o de rediseño de un subsistema.
  • Si detectas, de forma empírica (nada de corazonadas o instinto), que cada vez es más difícil aceptar cambios, entonces tu arquitectura es frágil ante el cambio. Da la alarma y prepárate para refactorizar.
  • Si no tienes problemas céntrate en producir funcionalidad. Olvídate de posibles futuros problemas que pueden no ocurrir nunca (YAGNI). Al fin y al cabo la calidad cuesta tiempo y dinero, si no necesitas más, ¿para que comprarla?

Bueno, este es mi enfoque personal. Como veis es muy cauto e intento no complicar el diseño hasta que no es realmente necesario. Llegué a esta forma de trabajar tras darme cuenta de que tenía tendencia a “chapar en oro” mi software, y hacer programación barroca. Me di cuenta que esto es un defecto y hay que balancear muy bien el esfuerzo que se dedica a mejorar el código contra el que dedicas hacer funcionalidad. Hay que llegar a un sano equilibrio.

Para finalizar, si tu proyecto no es ágil, olvídate de todo esto. En los proyectos no ágiles, el cambio es algo malo, que hay que penalizar, no aceptar. Por lo tanto no tiene sentido diseñar para aceptar el cambio. Como mucho tendrá sentido diseñar para cumplir el plan. Ahora empiezo a entender, porque algunos principios como YAGNI, KISS, SOLID o DRY no se han aplicado como debían en la industria, porque simplemente en un proyecto no ágil no tienen mucho sentido.

¡ Salud a todos y felices fiestas !

Read Full Post »


Como el post anterior sobre contratos cerrados me quedó un poco abstracto, en este voy a poner un ejemplo, con el que espero ser capaz de clarificar mi idea. Suponed que existen dos versiones de vosotros en dos mundos paralelos. En un mundo, el mundo verde, usáis scrum, y tratais de entregar funcionalidad real al final de cada sprint. En el otro mundo, el mundo rojo, usáis una metodología iterativa tradicional, donde al final de cada iteración entregais artefactos correspondientes a entregables de la cascada (diseño, análisis, capa de persistencia, etc). En ambos mundos el cliente os contrata para hacer el mismo proyecto, bajo contrato cerrado y con las mismas condiciones.

La siguiente figura ilustra lo que ocurre si aprovechando vuestras capacidades CMMI5, conseguís hacer una planificación perfecta durante la preventa y terminais el proyecto en tiempo, dinero y alcance según lo planificado en el contrato cerrado. Podéis observar que aunque en ambos proyectos se ha tenido un éxito rotundo, en el mundo verde se ha ido entregando funcionalidad desde antes. Pero, como el proyecto ha sido exitoso eso sólo son detalles que le importan a los frikies.

Entrega continua de funcionalidad al usuario

Proyecto exitoso (un mundo perfecto)

En el gráfico anterior, se ha medido la entrega de funcionalidad con respecto al paso del tiempo. Sin embargo no todas las funcionalidades son igual de importantes para el cliente. A la importancia de una funcionalidad en concreto lo llamamos valor. En scrum la funcionalidad se entrega por orden de ROI. El ROI es el balance entre el valor de una funcionalidad y su coste estimado. Cuanto más valor más ROI; cuanto menos coste más ROI. Sin embargo, en la práctica, las diferentes funcionalidades se van analizando, refinando y subdividiendo, hasta que éstas tienen un tamaño tal que nos permite, de forma razonable, implementarlas en un único sprint. Debido a esto las funcionalidades que se entregan al final de cada sprint tienen un tamaño similar. En este sentido, y de forma grosera, podemos tratar el factor coste dentro del ROI como una constante. Por lo tanto, de forma aproximada, Scrum entrega las funcionalidades con mayor valor primero, maximizando así el flujo de entrega de valor. Sin embargo en el mundo rojo la funcionalidad se entrega en cuanto se puede. El orden de entrega lo define, no el valor, sino el orden en el que se planificó (cascada) la entrega de todos los artefactos que componen una funcionalidad dada. En este sentido el mundo rojo entrega funcionalidad sin atender al valor, con lo cual el valor de cada entrega será “aleatorio”. Si en vez de medir funcionalidad entregada, medimos valor o utilidad entregada, el gráfico anterior se transforma en el siguiente:

Entrega de valor al usuario

Valor entregado en un proyecto exitoso (un mundo perfecto)

De nuevo ambos proyectos tienen éxito, pero en el segundo gráfico se detecta una diferencia aun mayor de entrega de valor entre los dos mundos. De nuevo esto es una curiosidad frikie.

Sin embargo podría haber ocurrido otra cosa. Ciertamente usando CMMI5 y nuestros mejores algoritmos de planificación y estimación, nuestro plan para el contrato cerrado es impecable y perfecto. Sin embargo el mundo es muy cruel, y el rival de nuestro cliente se adelanta y saca antes que nosotros un producto que es directa competencia del nuestro. El cliente desesperado decide salir a producción cuanto antes, con lo que haya, para minimizar perdidas debido a un “time to market” tardío. Lo siento chic@s, el negocio manda. Supongamos que esto ocurre en la iteración 7, veamos el gráfico.

Entrega de valor si entramos en producción inesperadamente

La competencia se nos adelantó (esto es más realista)

¡ Oh, qué pena ! Si la competencia hubiera tardado una iteración más, el mundo rojo hubiera podido entregar un 65% de valor. Desgraciadamente los muy desalmados decidieron sacar el producto a mitad de la iteración 7 y pilló al equipo del mundo rojo integrando la capa de persistencia con el gestor transaccional y haciendo el “documento de diseño de algoritmos concurrentes” de entrega obligatoria en esa fase de la cascada. Sólo pudieron entregar un 10%. En el mundo verde también hemos fracasado, pero al menos conseguimos entregar un 70% de funcionalidad. Desgraciadamente el “documento de diseño de algoritmos concurrentes” está en blanco y no tiene ni índice, que pena más grande, el señor auditor de calidad y responsable de metodología nos va a reñir.

Olvidémonos ahora de la competencia, supongamos que todo lo anterior fue una pesadilla y que realmente tenemos todo el tiempo acordado para entrar en producción, al fin y al cabo, es un contrato cerrado, ¿no? Lo que nos ocurre ahora es que le mentimos al cliente, para ganar el proyecto tiramos los precios y nuestros recursos no son tanto como los que dijimos. O tal vez no, tal vez simplemente no comprendimos tan bien los requisitos como pensamos y estimamos mal. O quizás el tiempo y el precio nos venían impuestos y pensamos que eran asumibles, pero no lo pensamos mucho. Estos escenarios, donde la planificación y estimación inicial no se corresponden con la realidad es el caso más común. Desafortunadamente el contrato cerrado nos impide renegociar tiempo y dinero y por eso constituyen un riesgo tanto para el cliente como para nosotros.

El siguiente gráfico ilustra una situación parecida:

Entregas de valor en proyecto cerrado con mala estimación

Nos hemos colado en la planificación (como siempre)

De nuevo scrum se centra en maximizar el flujo de valor entregado, con lo que conseguimos en este ejemplo un 60% de valor. El mundo rojo no se centra en el valor sino en artefactos con lo que el valor entregado es sólo el 35%. La hemos pifiado en los dos mundos, pero de nuevo insisto, scrum falla mejor.

A qué mundo preferís pertenecer, ¿al verde o al rojo? Espero haber dejado clara mi postura. Por supuesto los gráficos son ficticios.

Pero no cantéis victoria. Scrum sólo os dice que tenéis que entregar valor y funcionalidad al final de cada sprint, pero no cómo. El cómo conseguir esto es algo muy duro y complicado, y Scrum no te ayuda en nada en este aspecto. Necesitareis un equipo con talento y que sepa construir software de manera ágil. Esto parece material para otro post.

Read Full Post »


Hola a todos, aquí vuelvo a la carga con un nuevo post para desgracia de mis minoritarios lectores. El tema de los proyectos cerrados ya lo traté en otro post, explicando que en realidad el pensar que un proyecto está cerrado en alcance, tiempo y recursos es algo totalmente utópico. Sin embargo debido al ambiente de desconfianza que existe en nuestro sector entre clientes y proveedores, surgió esa mala bestia, el contrato cerrado, causante de tantos entuertos en nuestra profesión. Dado que ejercemos nuestra profesión en un ambiente hostil, nueve de cada diez veces vamos a encontrarnos en un proyecto con contrato cerrado. Los proyectos con contratos cerrados se han puesto siempre como ejemplo prototípico de un entorno donde Scrum y otras metodologías ágiles no podrían funcionar. Como este tipo de proyectos son los más comunes, muchos han usado esta aseveración para defender la postura de que trabajar en modo ágil es imposible en España (y alrededores). Yo no estoy para nada de acuerdo con esto, la verdad es que lo considero totalmente desacertado y un síntoma de lo mal que se está entendiendo el movimiento ágil. De hecho mi postura es radicalmente opuesta: los proyectos cerrados constituyen nuestro mejor aliado para implantar el modelo ágil en la empresa. O sea, no solo no pienso que el proyecto cerrado impida la gestión ágil, sino que es un aliado a la hora de hacer ver a nuestro entorno lo positivo que es Scrum. Todo pasa por una pequeña revelación: scrum es más eficiente que la cascada, sobre todo en proyectos cerrados. Aunque ya comenté algo al respecto en mi post anterior, quiero dar más detalle sobre mi postura a este respecto. Lo veremos a lo largo de este post, pero no os preocupéis, si se hace muy largo pienso dividirlo.

Como sabréis Scrum es un proceso iterativo, que al igual que cualquier otra metodología iterativa, divide la gestión y control del proyecto en pequeñas fases o iteraciones (sprints en scrum). Al final de cada pequeña fase se inspecciona el progreso del proyecto y se ajustan las planificaciones y la estrategia de desarrollo. El modelo clásico de cascada no es iterativo y se basa en una planificación y diseño detallado, tras la cual se realiza la construcción, y el producto no es inspeccionado y revisado por el cliente hasta el final. Obviamente el realizar la planificación y diseño detallado al principio es un error tremendo, ya que es cuando menos información tenemos, los requisitos están menos claros y la incertidumbre es mayor, con lo que seguro que nos vamos a equivocar en la planificación, y por mucho.

Es obvio, que una metodología iterativa es más eficiente que la cascada. En el caso de un contrato cerrado nadie nos libra de un análisis de requisitos con cierto detalle y una estimación afinada en la fase de preventa. Esto es intrínseco al modelo de contrato cerrado y concurso, necesitamos saber si podemos ir o no a presentarnos al proyecto y por cuánto dinero. Ya dije que esto es lo peor que podemos hacer, entonces, ¿de qué nos valen las iteraciones en un contrato cerrado? Simplemente para tener feedback frecuente. Esto redunda en un mayor control, por ejemplo:

  • Si el proyecto va muy mal, se puede detectar pronto, y cancelarlo con el menor coste para ambas partes. Algunos clientes (no todos) os agradecerán esta sinceridad e interés por no hacerle perder más dinero y tiempo.
  • Si el proyecto va muy mal, no se puede cancelar pero se puede retrasar, tal vez podáis negociar con el cliente un plazo extra de tiempo. Sí, sí, es contrato cerrado, pero el proyecto real no, en la práctica si el time-to-market no es muy crítico se puede negociar un retraso (aunque no te lo paguen).
  • Si el proyecto va muy mal, pero ni se puede cancelar ni retrasar, tendréis que usar la técnica de “más madera”. Si el cliente es bondadoso, podéis pactar un coste extra, aunque sea un contrato cerrado.
  • Si el proyecto va mal, pero se puede salvar, tomar las medidas correctoras pertinentes.
  • Si alguna circunstancia o requisito cambia os podéis enterar y aceptar el cambio de forma controlada. Sí, el contrato es cerrado, pero si el cliente decide cambiar un requisito o simplemente hubo un malentendido, lo correcto es aceptar el cambio de forma negociada. En caso contrario correis el riesgo de acabar el proyecto con éxito pero que no haga lo que quiere el cliente, y perder a éste de cara a futuros proyectos. Además, también las circunstancias y contexto del negocio cambia y no se pueden controlar, sería absurdo ponernos la venda en los ojos y pensar lo contrario.

O sea, que al planificar y cerrar la cosas al principio (contrato cerrado) estamos condenados a fallar. Pero usando una metodología iterativa podemos fallar por menos al controlar mejor el proyecto, e incluso aceptar cambios en el alcance si fuera necesario (aunque el contrato sea cerrado). También evita que andemos a ciegas hacia nuestra perdición. Estas ventajas están claras incluso en clientes muy tradicionales. La mayoría de ellos ya usan esquemas de trabajo iterativos, ya sea de forma explícita o implícita. En el último caso se suele tener un plan waterfall, pero muchas reuniones de seguimiento e hitos a intervalos regulares que implementan de facto un sistema iterativo. Otra variante se produce cuando el cliente divide un proyecto grande en múltiples fases, cada una de menos de tres meses, e intenta realizarlas de una a una en formato contrato cerrado. Desde el punto de vista del cliente esto es un ciclo de vida iterativo, desde el punto de vista del proveedor es simplemente una sucesión de concursos y contratos cerrados waterfall. Esta última forma de trabajar es bastante perversa, ya que no asegura al proveedor que realiza una fase del proyecto su participación en la siguiente, con lo que el incentivo por parte del proveedor para invertir en calidad disminuye, al no saber si se encargará de la evolución o mantenimiento prevista en la siguiente fase.

Como vemos el ciclo de vida iterativo es una mejora en proyectos cerrados, pero no es suficiente. Afortunadamente scrum no es sólo iterativo, sino incremental. En un proceso iterativo e incremental, al final de cada iteración no sólo se obtiene feedback de la marcha del proyecto, sino que se realiza una entrega parcial, que representa un incremento del grado de avance del proyecto. Existen varios procesos de desarrollo iterativos e incrementales, pero no todos ellos son ágiles. Los procesos iterativos e incrementales ágiles, como Scrum, entregan incrementos de funcionalidad, mientras que los demás entregan incrementos de construcción.

Un incremento de funcionalidad consiste en añadir nueva funcionalidad al sistema, que sea directamente útil al usuario, y que esté lista para entrar en producción, al final de cada iteración. Scrum sigue esta filosofía. El objetivo de cada sprint es entregar valor adicional al cliente, en forma de Product Backlog Items (PBIs) implementados y listos para entrar en producción. Por valor entendemos la utilidad, funcionalidad y/o rentabilidad de cada funcionalidad entregada. Los PBIs son unidades de funcionalidad, convenientemente analizadas y con una estimación de valor y coste. Pueden tener forma de historias de usuario o de casos de uso, según lo que se prefiera, pero eso no es lo importante. La estrategia de Scrum consiste no sólo en entregar valor al final de cada sprint, sino ir implementando los PBIs por prioridad, de forma que se entreguen primero los más importantes. La prioridad se calcula equilibrando el valor con el coste de cada PBI, de forma que dado el mismo coste se entreguen primero las de mayor valor.

La mayoría de las metodologías iterativas que se usan en el mundo empresarial no entregan incrementos de funcionalidad, sino incrementos de construcción. Un incremento de construcción consiste en entregar uno o más artefactos del proyecto al finalizar cada iteración. Ejemplo de tales artefactos son: documentos de diseño, esquema de BBDD, scripts de carga, capa de persistencia, pantallas. Estos artefactos, aunque necesarios para completar el proyecto, no aportan funcionalidad por si mismos. Estamos acostumbrados a que en cada hito, tengamos que entregar el documento de análisis, el de diseño, las tablas, etc. En el fondo esta forma de trabajar no es más que añadir un control iterativo a un ciclo de vida de cascada, de forma que cada iteración haga énfasis en una única fase de la cascada.

Otra diferencia importante entre los dos enfoques incrementales es en las reviews. En Scrum en cada sprint review se interactúa con el cliente, usuario y/o representante ya que vamos a enseñar funcionalidad. En esta reunión el cliente acepta o rechaza la nueva funcionalidad y nos proporciona un feedback de calidad sobre la funcionalidad del sistema. En el enfoque de entrega de incrementos de construcción no es posible interactuar con el usuario ni realizar aceptaciones de funcionalidad, ya que se entregan artefactos técnicos que son revisados por técnicos del cliente. En vez de aceptaciones de funcionalidad, se realizan aceptaciones de componentes tecnológicos. En este sentido no podemos tener feedback sobre la funcionalidad del sistema hasta bien tarde en el ciclo de vida de la aplicación (pruebas). Esto es totalmente ineficiente ya que el peor momento para detectar un error es al final, que es cuanto más caro es repararlo. También es bastante malo desde el punto de vista de la transparencia, ya que el usuario real no ve el sistema funcionando hasta el final. En realidad un enfoque iterativo incremental tradicional sigue siendo tan opaco para los usuarios como una cascada, ya que éste no puede interactuar con el sistema hasta el final. Esta forma de trabajar es un poco perversa, ya que al fin y al cabo, lo que el cliente conoce bien es la funcionalidad, y nos ha contratado porque sabemos de cosas técnicas. Lo lógico es que el cliente revise la funcionalidad, que es de lo que sabe y lo que le interesa, y que confíe en nuestro saber hacer. Tal vez esa confianza en nuestro saber hacer se ha visto envenenada por la moda de contratar “personal poco cualificado” y ofertar muy barato. Dicho todo esto, es obvio que Scrum proporciona una mayor transparencia y detecta los errores antes que una metodología iterativa incremental tradicional. Además proporciona resultados tangibles antes que un enfoque tradicional.

Como resumen, el hecho de aceptar un proyecto cerrado siempre conlleva un alto riesgo de no cumplir con las expectativas del cliente. Sin embargo scrum hace una mejor gestión que la cascada y otras metodologías no ágiles, al permitirnos:

  • Mitigar el riesgo de la estimación errónea. Si nos pasamos en la estimación al menos habremos entregado resultados tangibles y no artefactos “tecnológicos”.
  • Mitigar el riesgo de un lanzamiento prematuro debido a presiones de mercado. Si nuestros competidores lanzan su producto antes que nosotros, podemos ir a producción antes de lo esperado, ya que al menos tenemos algo con lo que ir a producción, en vez de documentos “técnicos”.
  • Ayudarnos a estimar mejor, al refinar mediante mejora continua nuestros procesos y usar timeboxing para que el proceso sea más predecible.
  • Ayudarnos a dar un precio más competitivo. De nuevo el timebox nos ayuda a enfocar nuestros esfuerzos y la mejora continua a aprender ser cada vez más productivos.
  • Mostrar al cliente el estado real del proyecto y entregarle valor de forma continua de forma que éste pueda empezar a confiar en nosotros. Tal vez el siguiente proyecto no sea tan cerrado…
  • Mitigar el riesgo/coste de cometer un error en el análisis funcional o aceptar un cambio. Detectar los errores cuanto antes es la forma más barata de solucionarlos, aceptar cambios de nuestros clientes es vital. Todo esto es posible ya que al final de cada sprint se puede mostrar funcionalidad, no tecnología, y por tanto recibir feedback del usuario.

En definitiva scrum falla mejor que otras metodologías a la hora de gestionar un proyecto cerrado. Los puntos claves que aporta scrum para conseguir todo esto son: transparencia con el cliente, mejora continua, iteraciones (sprints) y entrega incremental de funcionalidad real (valor).

Simplemente probad a gestionar vuestros proyectos cerrados con Scrum o similar, no es necesario que el cliente lo sepa de forma explícita. Seguro que la vais a pifiar (es un proyecto cerrado al fin y al cabo) pero lo haréis mejor que si hubierais usado la metodología “de toda la vida”, y vuestro cliente se sentirá mejor tratado y más satisfecho (pero no del todo). Construyendo pequeños éxitos, y poco a poco, vuestro cliente ganará confianza y podréis ir planteando otro tipo de relación, basada en la colaboración. Con el tiempo llegará el día que le podáis contar que usáis una cosa llama “agilismo”…

Ahora ya lo sabéis, no tenéis excusa, el agilismo va a llegar… incluso a los proyectos cerrados.

P.S. Uff, se ha terminado mi timebox de 2000 palabras, suficiente por hoy. En el siguiente post más sobre este tema, esta vez con dibujitos…

Read Full Post »


Hola a todos, lamento no haber podido escribir antes, pero tenía bastante trabajo acumulado y el deber me llamaba. Aprovecho que me iba a ir de fiesta esta noche y que al final no, para hacer algo útil con mi tiempo y escribir este post. Espero daros una crónica de lo que fue mi participación en la AOS2010, espero que un poco distinta y un pelín más crítica ;-)

Asistí junto con @ialcazar, @antoniodfr y @mcberros. Llegamos tarde, con la sesión de votación a mitad y un poco desubicados la verdad. Yo pensaba proponer una sesión llamada “los frameworks crean zombies” pero un tal Xavi Gost(@Xav1uzz) se me adelantó. Menos mal, porque con eso de llegar tarde, y ser mi primer open, estaba un poco cortado de verdad (a pesar del pequeño intento de @jmbeas de que saltara a la palestra). Mi compañero @antoniodfr no tenía muy claro si el formato open space iba a ser bueno o si por el contrario iba a degenerar en el caos. Al final se rindió al concepto de autoorganización y salió enamorado del concepto open.

Después vino una noche de parranda por los bares de Barcelona. Conté con la colaboración inestimable de Ramón Clariso y el inefable Aleix Cerecedo. Los bares al ver a una horda de agilistas por la noche de Barna iban cerrando a cal y canto, para que no entráramos en ellos ¡ y es que somos peligrosos ! Al final acabamos en un asador cerca del barrio de Graçia (¿está escrito bien?) donde tuvimos una animada charla con Roberto Canales(@rcanalesmora). Después el pobre Aleix tuvo la difícil tarea de buscar un bar en dicho barrio donde cupieran 40 personas. El pobre no dejaba de mirar atrás acojonado y diciéndome: “porque eres tu Enrique, sino salgo corriendo :-S “. Al final su plan “A” fue acertado y el sitio donde queríamos ir estaba vacío, pero en cuanto entramos quedo lo petamos. Desgraciadamente no servían mojitos, (mea culpa @kinisoftware) y lo peor es que no quedaba Moritz. Nos conformamos con gin-tonics y tercios de cerveza. A la llegada al hotel puse el despertador, este me informo amablemente que sonaría en sólo 3 horas, y cuando me quise dar cuenta ya estaba desayunando en el campus La Salle. Enrique, al lío.

Vayamos a las sesiones a las que asistí:

  • Coaching. Una sesión excelentemente moderada. Hubo un intercambio sano de ideas y experiencias, bastante refrescante. Allí me llamó la atención la intervención de Emma (¡dios, no se su twitter, que alguien me ayude, que quiero seguir a esta chica), según entendí es ScrumMaster quemada de muchas guerrillas en su empresa.
  • Software Craftsmanship. Propuesto por Xavi Gost y @ecomba. Bueno, nos contaron los principios del manifiesto y un poco como funcionaban, todo lo de los maestros y aprendices y demás. Me he leído el manifiesto y puedo decir que suscribo todo lo expuesto en él, ¿quién no podría estar de acuerdo? Es como los diez mandamiento, que aunque no seas judeocristiano, es probable que los pudieras firmar sin cargos de conciencia. Por ejemplo, el tema de educar mediante un sistema de maestro/aprendiz es obviamente la mejor manera de transmitir conocimientos. Por otro lado me sigue sin gustar el nombre o la analogía, ya que en el desarrollo de software no se construye nada. Los artesanos construyen pero en el software no se construye, se diseña. El que construye es el compilador. Por eso me sigue gustando más hablar de nosotros como ingenieros, y no como artesanos, porque nosotros diseñamos y el compilador construye. No veo por que el término ingeniero debe ser “evil”. En fin, es un tema de nomenclatura, porque a nivel de valores, que es lo que importa, me encuentro muy cercano a ésta forma de pensar. Un punto negativo en esta sesión fue que la moderación no fue muy efectiva, hablaron sobre todo Xavi y @ecomba, y la charla fue muy unidireccional (como me señaló alguien que no quiero nombrar).
  • La batalla de los frameworks. De nuevo con Xavi Gost, @ecomba y con la colaboración inestimable de @rcanalesmora en el papel del malo maloso de la película. Yo me lo pasé pipa y participé bastante, sobre todo para meterle caña a @rcanalesmora. Yo en esta estoy del lado del frente artesano y creo que los frameworks son armas de destrucción masiva a manejar con cuidado y mucha responsabilidad. El bando opuesto defendía que los frameworks te permitían contratar “personal poco cualificado” (a.k.a. “monos”) en masa para hacer los proyectos y ganar mucho dinerito calentito. El señor @rcanalesmora hizo una interpretación torticera de unas palabras que le dije la noche anterior, entre vinitos, y yo le respondí dándole cañita brava (pero con cariño).
  • Manipula. La señorita @rlaina nos dio una charla sobre el tema seguido de un debate. Tanto Emma como @jmbeas contaron sus problemas, que se parecen sospechosamente a los que tenemos todos. El problema es que cuando el debate se ponía interesante se nos acabó el tiempo y ¡ rompimos el timebox ! Cometimos el feo pecado de extender la charla a pesar de los heroicos esfuerzos de @amaliahern de salvar nuestras almas. La verdad es que el debate estuvo interesante, pero nos saltamos media comida.
  • Como tratar con locos paranoicos. Propuesta y dirigida por Xavi Albadalejo fue una de las charlas más interesantes. Usando la técnica de identificación de causas raíces analizamos porqué muchas personas recurren al Command & Control (a.k.a. “aquí se hace lo que yo digo”). Llegamos a la conclusión de que existían dos tipos de jefes autoritarios: los paranoicos y los desconfiados. Si te toca el primer tipo es mejor plantearte si dejar la empresa, ya que es una señal de que la cultura empresarial fomenta este tipo de personas como jefes. Si te toca el segundo tipo entonces hay esperanza. Lo curioso es que las técnicas que fuimos sacando para desactivar el ordeno y mando de un jefe desconfiado es simplemente… usar Scrum Efectivamente las técnicas propuestas por Scrum tienen como resultado aumentar la transparencia y esto acaba por aumentar la confianza. Muy enriquecedora esta sesión.
  • Diseño ágil. En esta sesión estuve bastante activo. Hablamos de como conseguir un buen diseño OO sin tener que hacer un diseño detallado al principio del desarrollo, práctica que va en contra de los principios ágiles. Yo conté mi experiencia, de que usando sólo TDD junto con un refactor continuo y agresivo, llegas a un diseño bueno. Sólo necesitas hacer al principio un pequeño diagrama de “cajitas” con la arquitectura de alto nivel. El detalle de cada “cajita” te la da el TDD+Refactor. También hice notar que esto por otro lado no te resolvía aspectos como el rendimiento y la seguridad, que tal vez sí hay que planearlos más de antemano. Algunos compañeros comentaron que ellos ponían pruebas de rendimiento en el build nocturno y que pedían a un experto en seguridad, que atacara el entorno de demo cuando el quisiera. Una aportación muy interesante. También se habló de las revisiones de código, y hubo unanimidad en que eran necesarias. Yo sostuve que la programación por parejas era equivalente a una “revisión de código continua”. Un asistente comentó que además ellos tenían un “moderador de proyecto”, que era externo al proyecto y neutral al equipo, que hacía revisiones de código. A mi me pareció una excelente idea. Ellos usaban un plugin de JIRA llamado Crucible, para hacer dichas revisiones. Lo tengo que probar. Todos estuvimos de acuerdo en que el UML era bueno para hacer bocetos de ideas y arquitectura de alto nivel. También consensuamos que había que hacer toda la documentación técnica necesaria para hacer el mantenimiento del sistema, pero por lo general, cuando el código está bien diseñado, éste es bastante legible, y necesitas menos documentación de la necesitarías normalmente.

Por supuesto hubo otras charlas, que supongo cada uno habrá comentado en su blog. Finalmente vino la retrospectiva, dinamizada, de forma genial, por el señor Ariel Ber (no se si tiene twitter). Se habló de las “AgileGirls”, de hacer un “Scrumbar” y de hacer el siguiente Open más grande. En concreto yo creo que una mejora para el AOS2011 debería ser que la gente participara más, me explico. En muchas sesiones la charla estuvo dominada por los “pesos pesados” y los “gurus” y vi a la gente un poco cohibida, lo que creo que impidió que se generara más debate. Yo mismo soy culpable de ese pecado y en muchas sesiones me hubiera gustado participar más, pero no me atreví. Tal vez en el siguiente open solucionemos eso.

Por supuesto hubo una segunda noche de fiesta, comimos en el “divinus”  y terminamos trasegando mucha cerveza y sangría en el “Ovella negra” (¿?) mientras @ydarias y compañía hacían lobby para que la siguiente AOS se celebre en Canarias (¡yo voto por vosotros!)

Quiero hacer mención especial de @amaliahern, que estuvo de fotógrafa e iba de sesión en sesión procurando que se cumpliera el horario. También creo que Ariel Ber estuvo excelente durante la retrospectiva, como comenté anteriormente.

Por último quiero poner mi opinión sobre un debate “silencioso” que se produjo de forma soterrada durante muchas sesiones: certificaciones sí, certificaciones no. De hecho hubo una sesión explícita sobre las certificaciones. Yo personalmente me he certificado CSM con Alan Cyment y Ariel Ber. Os recomiendo su curso, aprendí más sobre el espíritu de Scrum que en cualquier libro. Entiendo perfectamente a los que les da miedo que las certificaciones se perviertan y terminen siendo un modo fácil para que las grandes empresas se pongan el sellito de ágil y vendan por ahí lo que no son. También se corre el riesgo de que el agilismo quede preso de grandes consorcios certificadores. Sin embargo queda claro en todos sitios lo que significa ser CSM: que simplemente has dado un curso y que has comprendido lo que es Scrum, nada más. De comprender lo que es Scrum a practicarlo de verdad hay un mundo. De hecho la certificación que dice que usas Scrum con éxito no es la CSM, sino la CSP, en la que debes acreditar experiencia y pasar un “peer review”. De todas formas, sería de incautos juzgar la experiencia de alguien sólo por su certificación. Creo que los certificados son necesarios, pero no indispensables, y que tienen sus peligros, pero no por ello se debe generar un sentimiento de animosidad entre ambos bandos. Pensad, ¿se necesita ser universitario para ser un buen desarrollador de software? Por supuesto que no ¿Debemos abolir los títulos universitarios de ingeniería de informática por ello? Rotundamente no, aunque algunos políticos quieran. Pues lo mismo con las certificaciones.

En fin señor@s, yo vengo muy contento del AOS2010, y espero un AOS2011 aun mejor, tal vez en Canarias ;-)

P.S. Las fotos que tengo mejor no las cuelgo, curiosamente parecemos todos unos borrachos por la noche…

P.S.S. Señor @jmbeas péguele un tiro en la cabeza a su zombi, es para que no sufra el pobre :-D

Read Full Post »


… y lo sabéis en el fondo de vuestro corazón, ¿o no? Bueno, a lo mejor sí que existen, pero a mi me parece que no. En este post os voy a contar mi punto de vista sobre esto de los proyectos cerrados ¡ Bien, hoy no hay TDD, menos mal ! Creo que es importante tratar este tema de los proyectos cerrados, sobre todo en relación a las metodologías ágiles, ya que está muy extendida la idea de que dichas metodologías no pueden aplicarse en proyectos cerrados. Mi idea es que eso de los proyectos cerrados no existe, y que cuando se dice que un proyecto es cerrado en realidad estamos soltando una buena mentira.

¿Os acordais del teorema CAP? Bueno, pues lo que voy a contar a continuación se parece mucho. A alto nivel y desde el punto de vista de planificación y preventa de un proyecto hay tres variables: el alcance, el tiempo de entrega y el coste unitario. Veamos que son estas tres variables:

  • Alcance. El alcance es la cantidad de funcionalidad o de historias de usuario que va a tener el proyecto. También se puede interpretar como el tamaño del proyecto. En los proyectos de alcance pequeño sólo hay que implementar unas pocas funcionalidades, en los de alcance grande tenemos una lista de requisitos grande (o unos pocos requisitos enormes). Algunos factores no funcionales, como la complejidad de las tecnologías implicadas en el proyecto, o la complejidad a nivel de interlocución, también pueden afectar al alcance.
  • Tiempo de entrega. Cuanto tiempo tenemos para terminar el proyecto.
  • Coste unitario. El coste de mantener un equipo de trabajo y toda su infraestructura por unidad de tiempo. Cuanta más gente en el equipo, mayor coste unitario. Cuantas más máquinas y más caras, más coste unitario. Cuantas más licencias de pago tengamos, más coste unitario. No confundir con el coste total, que lo da la suma del coste unitario a lo largo de todo el proyecto.

Bien, todo sencillo. En este contexto podemos definir un proyecto cerrado como aquel que tiene un coste unitario, tiempo de entrega y alcance fijo. Sin embargo esto en la práctica no existe. Un proyecto cerrado sólo podría existir en un mundo estático, donde el entorno no cambia y las cosas son totalmente predecibles y repetibles, y el mundo real no es así. En la realidad las necesidades de negocio cambian durante el desarrollo de los proyectos, los clientes y usuarios se equivocan y cambian de opinión, la productividad de un equipo de desarrollo cambia con el tiempo. Sólo un novato puede pensar que un cliente no va a cambiar de opinión o que un acta de reunión se va a respetar (en Alemania tal vez, en España no). He visto demasiadas actas de reunión y contratos y análisis funcionales haciendo compañía al papel higiénico (hay que reciclar). Todo esto lo sabe la gran mayoría de los profesionales y por ello en la práctica tenemos mecanismos de defensa como:

  • Las notas de cambio de alcance y la gestión del cambio. Es el mecanismo de defensa típico del proveedor. ¿Que el cliente cambia el alcance? Pues pagas dinero. La opción de quitar alguna funcionalidad a cambio no es tan popular.
  • Las cláusulas de penalización si un proyecto se retrasa. Con esto el cliente se defiende tanto de un proveedor en el que no confia como de posibles retrasos debido a imponderables.
  • Precio total del proyecto cerrado. Como el anterior permite al cliente defenderse de proveedores malvados o ineptos o simplemente ante cualquier tipo de desgracia acaecida durante el proyecto.

Fijaros en la contradicción, todo el mundo habla de que los proyectos de verdad son cerrados, pero todo el mundo asume que habrá retrasos, malentendidos, incompetencia, imponderables y cambios de necesidades de negocio. Todo el mundo hace proyectos cerrados, pero a la vez usan tácticas de defensa. El problema real es que la gente tiene en cuenta la realidad, pero las metodologías tradicionales no. Las metodologías tradicionales asumen que una vez pasada la fase de análisis de requisitos (o preventa como se llama en España), se puede hacer un proyecto cerrado, ya que presuponen que el mundo es estático e inamovible. Como la realidad es caótica y cambiante, pero todos se empeña en usar metodologías pesadas, se producen estas contradicciones. Usar metodologías basadas en concepciones irreales es peligroso para tu negocio, no me extraña que la mayoría de los proyectos no sean exitosos. En vez de usar metodologías que no se ajustan a la realidad y que tienen una visión inocente respecto al nivel de caos de un proyecto real, es más eficiente usar metodologías diseñadas con la cruda realidad en mente, y que se basan en aceptar el cambio y gestionarlo. ¿Cúales pueden ser estas metodologías? Mmmm, ah, sí, eso raro del agile.

Visto que el caos de la realidad nos impide tener proyectos cerrados, ¿qué hacemos? Tal vez no podamos cerrar las tres variables, pero si algunas de ellas y jugar con las demás. Veamos que posibilidades tenemos:

  • Alcance abierto, coste unitario y tiempo de entrega cerrado. Este tipo de proyectos es el clásico ejemplo en las metodologías ágiles. Se tiene un tiempo de entrega cerrado, ya que en estos casos el time to market suele ser vital en el negocio. Dada una estimación del alcance, se propone un equipo cerrado (coste unitario cerrado). Se cierra el equipo ya que normalmente añadir o quitar miembros a un equipo suele ser malo para la productividad (costes de formación, ponerse al día con el proyecto, etc). Durante el proyecto se acepta cualquier cambio de alcance, pero al acabar el tiempo pactado, se entrega. Esto permite ofertar a coste total cerrado. El proyecto se considera exitoso si el alcance conseguido es similar al estimado. Más vale estimar bien, sino el cliente quedará descontento.
  • Alcance cerrado, coste unitario cerrado y tiempo de entrega abierto. Como ya he comentado con anterioridad este caso no se produce en el mundo real, excepto tal vez, en proyectos pequeños, debido a que el alcance siempre cambia, ya sea por cambios en necesidades de negocio o por malentendidos. Aun suponiendo que el alcance es cerrado, el que el tiempo de entrega sea abierto, implica que la eficiencia o productividad del equipo varía o se ha estimado mal la capacidad del equipo. Otra posibilidad es que el time to market no afecte al valor del proyecto, pero esto es poco realista. En este caso el coste total del proyecto es abierto, ya que no sabemos por cuanto tiempo vamos a tener al equipo trabajando.
  • Alcance cerrado, coste unitario abierto y tiempo de entrega cerrado. De nuevo como el anterior este caso no es muy real, tal vez se puede dar en aplicaciones pequeñas pero con un time to market muy estricto. Para conseguir llegar a la entrega se invertirán los recursos que hagan falta. De nuevo el coste total del proyecto es abierto.
  • Alcance y coste unitario abierto, pero tiempo de entrega cerrado. Se corresponde con un proyecto crítico, no sabemos exactamente lo que se va a implementar, pero tiene que estar listo en una fecha concreta. Para conseguirlo se pondrán todos los recursos que sean necesarios.
  • Alcance y tiempo de entrega abierto, pero coste unitario cerrado. Esto es un proyecto sin prioridad ni ningún tipo de urgencia. Puede ser un proyecto personal o entre amigos.

El tipo de proyecto que os podéis encontrar más frecuentemente en la realidad es el primero, el que deja abierto el alcance y cerrado lo demás. Qué casualidad que es el tipo de proyecto en el que se centran las metodologías ágiles. Este tipo de proyectos tiene unas cualidades muy interesantes: el coste total es cerrado y por otro lado se ajusta mejor a la realidad. Esto es bueno para el proveedor, ya que evita entrar en perdidas y puede asegurarse un beneficio económico. También es bueno para el cliente, pero sólo si el alcance conseguido es suficientemente bueno.

Esta circunstancia pone al cliente en una posición de debilidad con respecto al proveedor. Muchas consultoras sin escrúpulos se aprovecharon de esto en el pasado. Por eso los clientes ahora demandan “proyectos cerrados”. Lo que en realidad hacen es protegerse contractualmente. Es muy raro que un cliente admita “alcance abierto” debido a esa debilidad. Sin embargo si la relación cliente/proveedor es de una gran confianza y la experiencia pasada sea buena, si puede admitir este modelo de proyecto con alcance abierto, al fin y al cabo lo que le suele interesar al cliente es protegerse de proyectos que no se acaban nunca y que consumen dinero sin fin. Si el fracaso del proyecto no supone un gran perjuicio para el cliente, aumenta la posibilidad de que éste se preste a un contrato abierto. Otro caso es el de los proyectos internos, donde es absurdo penalizarse a uno mismo, y es mejor aceptar la realidad. En este caso el poder hacer “lo máximo posible” en un tiempo y coste acotado es bastante atractivo.

En el resto de los casos el cliente querrá un modelo de penalización o bien de precio cerrado. Esto no significa que no tengamos un proyecto con alcance abierto, sino que tenemos un contrato cerrado. Sólo debemos aceptar contratos cerrados si estamos muy seguros de poder cumplirlos o si estamos muy desesperados. Para tener esa seguridad nuestra organización debe ser lo suficientemente madura como para poder hacer estimaciones certeras. En este caso se trata de estimar el alcance, y en función de esta estimación saber que coste unitario hay que invertir para cumplir los plazos. Esto no es fácil, sobre todo si tenemos en cuenta que el coste unitario no afecta de forma muy predecible a la productividad del equipo. Podemos gastar mucho pero mal, por ejemplo comprando caras licencias de productos que no son adecuados o poniendo un pelotón de becarios en vez de unos pocos desarrolladores expertos.

En cualquier caso debemos estar preparados para lo peor. Sabemos que aunque el proyecto sea abierto el cliente normalmente se protegerá con un contrato cerrado, asi que ¿qué puede ocurrir si fracasa el proyecto? Es decir, ¿que pasa si el alcance logrado no da el valor suficiente al cliente? En estos casos el cliente tiene diferentes mecanismos para protegerse:

  • Si lo más importante para el negocio es alcanzar un nivel de funcionalidad aceptable, se da un tiempo extra al proyecto, a cambio de una penalización económica debido a los “daños” de no tener el sistema a tiempo.
  • Si lo que realmente importa es el time to market, se pone en producción pero se penaliza al proveedor en función de la cantidad de funcionalidad que falte, para compensar los inconvenientes de que el sistema no tenga suficiente funcionalidad.
  • Precio cerrado. El proyecto es precio cerrado, y el cliente no te pagará ni un céntimo más del pactado. Si el time to market es lo importante tendrás que aumentar el coste unitario para reforzar el equipo. Si lo importante es la funcionalidad, tu equipo estará más tiempo del planificado. Combinaciones de ambos escenarios son bastante típicas. Todo esto puede lleva a proyectos con poca rentabilidad o pérdidas si no consigues estimar bien.
  • Te demandan y/o devuelves el dinero más el perjuicio recibido por el cliente debido a no conseguir tener la aplicación.
  • Si aplicas una metodología que lo permita, se puede abortar el proyecto en cuanto se vea que se va a fallar. Las metodologías ágiles son especialmente adecuadas en este sentido. Si se falla al principio, el cliente aun está a tiempo de contratar a otro, con lo que tiene menos perjuicio. Desgraciadamente en España es raro ver proyectos abortados aunque claramente se encaminen al fracaso.

¿Cómo afrontamos los contratos cerrados? ¿Nos rendimos y hacemos lo “mismo de siempre”? Muy al contrario, lo ideal en estos casos es usar metodologías ágiles, aunque la idea parezca de poco sentido común. Desde el punto de vista de los contratos cerrados, las metodologías ágiles son muy eficaces, ya que nos permiten gestionar el riesgo mejor y por otro lado nos permiten tener estimaciones precisas. Uno de los pilares de dichas metodologías es el uso de ciclos de feedback frecuentes, lo que nos permite:

  • Enterarnos rápidamente de los cambios de alcance. Mediante entregas frecuentes y desarrollo incremental el cliente tiene acceso rápidamente a la funcionalidad con lo que nos puede advertir de los cambios de requisitos. Este es un mecanismo muy útil para mitigar uno de los riesgos más típicos: construir funcionalidad que el cliente no quiere.
  • Aceptar cambios e implementar la funcionalidad más importante primero. Cuando se llegue a la fecha de entrega, al menos se habrá cubierto la funcionalidad más importante, con lo que la posibilidad de fracasar disminuye.
  • Mediante las reuniones diarias nos enteramos de los posibles impedimentos al proyecto, lo que nos permite tomar acciones correctivas, mitigando riesgos tecnológicos y organizativos.
  • Análisis de viabilidad frecuente. Por ejemplo, en Scrum, podemos decidir al final de cada iteración o sprint, cancelar el proyecto, de acuerdo al feedback del usuario y de los equipos de desarrollo.
  • Las estimaciones mejoran más rápidamente, ya que al tener un feedback más rápido, tenemos más datos y por lo tanto podemos ajustar mejor las estimaciones. Con una metodología pesada el feedback es al final del proyecto, y las estimaciones sólo se pueden ajustar al final del proyecto. En Scrum ajustas las estimaciones al menos una vez por iteración (sprint). En kanban, una vez cada vez que se termina una historia de usuario.

También hay que tener en cuenta que cada sprint o iteración se puede considerar como un proyecto en si mismo, pero de alcance muy pequeño y duración corta. Si el alcance es pequeño y la duración corta,  pensar que el alcance está cerrado, sí es una buena aproximación a la realidad. Al contrario que en un proyecto real, durante un sprint, hay muy poco tiempo, y por lo tanto poca probabilidad de que el alcance del sprint cambie. Podemos considerar pues, que cada sprint es un verdadero proyecto cerrado en el sentido estricto del término. De esta forma gestionar un sprint sí es sencillo, comparado con gestionar un proyecto. De todas formas, en proyectos muy cambiantes (o altamente caóticos), el alcance cambia incluso durante el sprint. En estos caso Scrum puede que no sea la mejor opción, y habría que utilizar enfoques más ágiles todavía, como kanban o el agilismo minimalista.

Como vemos, los proyectos cerrados no existen, pero los contratos cerrados sí, lo que hace los proyectos sean arriesgados para el proveedor. Sin embargo el mito de que una metodología ágil no es útil con contratos cerrados se cae bajo su propio peso. Al contrario de lo que muchos piensan, las metodologías ágiles permiten una mejor estimación y gestión del riesgo de un proyecto con contrato cerrado, además de incorporar de forma natural la gestión del cambio. Tal vez, cuando tu cliente vea que no lo engañas y que cumples tus contratos, te deje hacer un “contrato abierto”.

Read Full Post »


Hola, seguimos con la polémica del TDD, pero no temais, en este post no voy a hablar de TDD (al menos no mucho). En el anterior post defendí que si se hacía bien el TDD, con su refactor y que si además se complementaba con un pair programming, la necesidad de métricas estáticas de calidad de código desaparecen. Comentarios a dicho post por parte de @jmbeas, Chuidiang e @ydarias indicaban que mi postura era correcta en un equipo experto, pero que si tenías equipos menos maduros, entonces necesitabas estas métricas porque los equipos no iban a hacer TDD, refactor y pair programming, ya sea por inexperiencia o por simplemente no querer. Bien, esto es cierto, de hecho es interesante que al enseñar TDD y refactor a equipos novatos,  usemos análisis de código estático para ver como de forma incremental, y emergente, el código alcanza una buena calidad.

En el fondo, mi problema es que pienso que los equipos que no hacen TDD o pair programming, sencillamente no están haciendo agilismo… Enrique, no te metas en más líos, mejor digamos que sencillamente no están usando una buena metodología. En el resto de este post voy a explicar tan inverosímil afirmación.

El agilismo propone un metaproceso para definir un proceso de desarrollo e ir evolucionándolo en el tiempo, con el objetivo de adaptarnos a los cambios en nuestro entorno y mejorar dicho proceso de forma continua, de manera que maximicemos el valor entregado al cliente. No vale con que el proceso sea bueno hoy, sino que debe ser mejor mañana y no debe quedarse obsoleto. Y por mejor entendemos que entregamos más valor al cliente en menos tiempo y con menos coste. Obviamente, para poder implementar el proceso de desarrollo en la realidad, y poder hacer mejora continua, se nos propone un conjunto de buenas prácticas. Mi pregunta es, ¿cuál es el conjunto mínimo de buenas prácticas para considerarnos ágiles? Dicho de otra forma, ¿cuál es la metodología ágil más ligera posible? Dada la definición de agilismo anteriormente expuesta, la metodología ágil más ligera, es aquella que sólo obliga prácticas que proporcionen lo más rápidamente posible información de los problemas del proyecto, y nos ayuden a resolverlos cuanto antes. Armados con unos ciclos de feedback rápidos, que nos informen sobre problemas en el proyecto, podemos practicar mejora continua, y terminaremos con una metodología que es perfecta para nuestro entorno de trabajo específico, y que va a evolucionar para adaptarse a cualquier imprevisto.

Dicho esto, hay que tener en cuenta que los problemas nos lo podemos encontrar a múltiples niveles: estimación y planificación, desarrollo, build y pases de entornos, explotación, etc. Necesitamos pues, ciclos de feedback y mejora continua en cada uno de esos niveles. Obviamente algunos de dichos niveles escapan a mi control, pero al menos planificación y desarrollo sí están bajo mi control. Al conjunto mínimo de prácticas, que te permiten conseguir mejora continua de forma efectiva, lo llamaré agilismo minimalista.

A nivel de control de proyecto y mejora continua lo mínimo que puedes hacer es:

  • Retrospectiva al final de proyecto. Hay que reunirse para saber las causas del éxito o fracaso del proyecto, y que cosas se pueden mejorar y cómo. Es el nivel básico de mejora, aprender del resultado de un proyecto para el siguiente. Debería participar la dirección de la empresa también y el cliente.
  • Múltiples reuniones de seguimiento del proyecto, a ser posible a intervalos regulares, predecibles y ni demasiado largos ni cortos. Un ejemplo de reunión de seguimiento es la retrospectiva de sprint dentro de SCRUM. Otro ejemplo es la demo de final de sprint, este último más orientado a obtener feedback del cliente. Nos permite enterarnos rápidamente de los problemas que se producen durante el proyecto sin esperar a que acabe. Si hay algún problema podemos tener la oportunidad de solucionarlo. También podemos ajustar nuestras estimaciones con la realidad del proyecto, y aprender a estimar mejor en el futuro. Se puede involucrar a todos los participantes en el proyecto, al fin y al cabo no se hace todos los días. Esto es importante para que la información del estado del proyecto llegue a todo el mundo por igual y no se quede información escondida en nichos. También debe participar un representante del cliente, para ver como va el proyecto, proporcionar información adicional y aclarar dudas.
  • Reunión diaria o daily scrum. Es un nivel de feedback más rápido, diario, que involucra a los miembros de un mismo equipo y al menos un responsable. En proyectos grandes pueden haber varios equipos cada uno con su propia reunión diaria.
  • Reunión de emergencia. Para solventar cualquier problema grave y no previsto, detectado mediante cualquier mecanismo.

A nivel de planificación y estimación:

  • Dividir el trabajo en unidades manejables. Dichas unidades deben ser estimables, representar un incremento en el valor entregado al cliente, concisas y claras, de un tamaño similar entre si, independientes entre si, tener un criterio de aceptación y no demasiado grandes. Esto se suele conocer como historias de usuario. La importancia de las historias de usuario es que te proporcionan una unidad de planificación y estimación que está bien correlacionada con el valor del proyecto desde el punto de vista del cliente. El criterio de aceptación es importante para saber cuando se ha terminado de implementar la historia.
  • Revisa las estimaciones frecuentemente, teniendo en cuenta los resultados obtenidos en las retrospectivas y reuniones anteriormente mencionadas. Si las historias no fueran pequeñas, independientes y de tamaños similares, el ajuste de las estimaciones basándonos en lo que pasó en otras historias sería prácticamente imposible.
  • Refina y revisa la definición de las historias frecuentemente. Tal vez a intervalos regulares (SCRUM sprint planning) o tan pronto como te sea posible (kanban). Para ello hay que hablar con el propio usuario, o en su defecto con un experto de negocio.
  • Implementa primero las historias con más valor. Esto maximiza el valor entregado al cliente. También nos evita tener que implementar historias que pueden cambiar o quedar obsoletas con el transcurso del tiempo.

De momento a nivel de gestión y planificación, el agilismo minimalista no es ninguna sorpresa. El punto es que si no implementas todas estas buenas prácticas, no eres ágil. Simplemente no vas a poder reaccionar a los cambios en tu proyecto ni mejorar la forma de trabajo. Casi todas estas prácticas las realizan todas las empresas serias que conozco, excepto la reunión diaria, las historias de usuario y la implementación por orden de valor. Si no practicas la reunión diaria tendrás problemas ocultos y enquistados al menos hasta la próxima reunión de seguimiento, que será dentro de ¿entre 2 y 4 semanas? ¿No es muy ágil cierto? Hasta aquí casi todos estareis de acuerdo, pero todo esto no es suficiente para reaccionar ante problemas y mejorar en un proyecto software. Necesitamos tener en cuenta otro aspecto, la ingeniería.

Desde el punto de vista de mejora continua de la ingeniería y desarrollo:

  • Programación por parejas. Es otro ciclo de feedback, esta vez sobre el diseño y la calidad de código. Lo podemos considerar una revisión de código continua o una QA continua. El feedback proporcionado por un compañero a la persona que está tecleando es rapidísimo, del orden de segundos.
  • TDD. Nos permite saber si nuestro código funciona, o si la modificación que hemos hecho rompe algo. Feedback del orden de minutos.
  • Refactor frecuentemente. Dentro de un ciclo de TDD para garantizar que se hace a menudo, y guiado por la programación por parejas, nos permite mejorar de forma continua la calidad de nuestro código.
  • Integración Continua. Feedback a nivel de horas, que nos permite detectar problemas de integración.

Bien, con esto quiero decir que el agilismo minimalista necesita de mejora continua no sólo a nivel de gestión, sino a nivel de ingeniería, con lo cual necesitas hacer TDD, refactor, pair programming e integración continua, como mínimo, para ser ágil. Si no haces integración continua no detectas los problemas de integración hasta que no haces un pase, ¿es eso ser ágil? Si no haces TDD no detectas si has roto funcionalidad al introducir un cambio hasta que no lo prueba el equipo de QA, ¿es eso ser ágil? Además si no haces TDD no puedes hacer integración continua, sino como mucho, compilación continua. Si no haces pair programming no detectas errores de programación o fallos de diseño hasta dios sabe cuando, ¿es eso ser ágil? El refactor frecuente te permite arreglar tu código, sin necesidad de esperar al super arquitecto/guru. Lo importante es que todas estas prácticas se realimentan y se producen sinergias positivas entre ellas. Cada una cubre cosas que la otra no. Si quitas una sola el edificio se empieza a derrumbar. Por ejemplo si quitas el pair programming puedes introducir fake TDD o simplemente saltarte el refactor. Si quitas el TDD te cargas la integración continua. Las necesitas todas, no son opcionales, son obligatorias.

Ya contamos en la CAS2010 nuestra experiencia de implantación del agilismo. Hubo un momento que teníamos sprints, retrospectivas, etc. Pero no teníamos TDD ni pair programming ni se hacía refactor, y mucho menos integración continua. Eso no funcionaba. Asi que lo siento, a aquellos que piensen que puedes hacer agilismo con un equipo que no controle estas técnicas y no esté dispuesto a hacerlas, os aviso: no va a funcionar, no basta con el sprint planning y el daily scrum, no vas a ser ágil, necesitas prácticas ágiles de ingeniería y gente capaz de llevarlas a cabo.

Afortunadamente parece que hay gente por ahí de acuerdo conmigo, sino leed lo mismo que digo pero explicado de otra manera en este blog de Luis Artola. SCRUM y KANBAN sólo se ocupan del nivel de gestión y planificación de proyecto, pero no de la ingeniería. Para que tu proyecto sea exitoso, necesitas también buenas prácticas de ingeniería y trabajadores capaces de llevarlas a cabo. Muchos piensan que son ágiles porque aplican prácticas ágiles a nivel de planificación y gestión, pero se olvidan de la ingeniería. Esta es una maldición eterna en el mundo de los proyectos software, parece que por poner una capa de gestión se arreglan todos los problemas, pero nadie presta atención a lo más básico, la ingeniería y la capacidad profesional de los “pikachus”.

En resumen, lo mínimo que puedes hacer para considerarte ágil (agilismo minimalista) es: pair programming, TDD+Refactor, integración continua, reuniones diarias, reuniones periódicas de seguimiento (internas y externas para el cliente), retrospectivas de proyecto y planificación y estimación basada en historias de usuario. Si te falta, aunque sea una sola de estas prácticas, no eres ágil.

¿Y las demás buenas prácticas? Bueno, para mi no forman parte del agilismo minimalista, las considero muy dependientes del entorno en el que se mueva cada uno. Aquí es, donde creo yo, que se debe aplicar eso de probar a usar una buena práctica, experimentar y ver si va con tu proyecto o no. Lo importante es que con el agilismo minimalista irás descubriendo cuales son útiles y cuales no. Por ejemplo, a nosotros los sprints no nos han funcionado bien, por eso estamos pensando en pasar a kanban, pero conservando los principios del agilismo minimalista. Quizás esto de agilismo minimalista+kanban sea algo parecido al scrumban que he escuchado por ahí. En cualquier caso el resto de las prácticas debéis experimentar con ellas antes de adoptarlas en serio o no.

Corolario: si ves que necesitas métricas estáticas de calidad de código, es una señal de que no eres ágil, algo falla (pesaito soy). Saludos y ahora me voy a dormir, que ya me vale.

Read Full Post »

« Newer Posts - Older Posts »

Seguir

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

Únete a otros 50 seguidores