mapa con brujulaEn el artículo anterior de esta serie vimos los siete principios Lean y sus bases fundacionales esenciales. En esta segunda parte de la guía vamos a repasar cada principio Lean y reflexionaremos sobre las prácticas Ágiles que los implementan.

Los siete principios Lean

Repasando del artículo anterior, los siete principios Lean son:

  • Respetar a las personas
  • Eliminar el despercidio
  • Posponer el compromiso
  • Crear conocimiento
  • Entregar rápidamente
  • Construir la calidad desde adentro
  • Optimizar el total

Vamos a repasar estos principios y veremos sus razones de ser y las distintas prácticas Ágiles que nos ayudarán a cumplirlos.

Respetar a las personas

¿Quién debería estar involucrado en la mejora de los sistemas? ¿Es el trabajo principal de la gerencia? ¿O de la gente que hace el trabajo mismo? Para Henry Ford la respuesta era la gerencia: para él, la gerencia era mucho más inteligente que los trabajadores y sólo se podía confiar en ellos para decidir cómo mejorar la producción de automóviles. Ford tenía muy poco respeto por el conocimiento de sus trabajadores.

Hay tres problemas con este pensamiento. Primero, si bien permitió construir un proceso estático muy bueno para construir un tipo de auto, el proceso no ofrecía ninguna flexibilidad. Recordemos la frase famosa de Ford que decía que las personas podían tener un auto "de cualquier color siempre y cuando ese color fuera el negro". Segundo, la mayoría de los procesos no son estáticos; siempre están cambiando. Los trabajadores de todas las líneas siempre van a comprender las condiciones locales de un entorno que cambia mucho mejor que la gerencia porque ellos tienen mejor conocimiento de lo que ocurre. Y es así cómo se cambian los procesos en la línea de producción. Por último, Ford podía exigirle a sus trabajadores en una época donde el valor principal de los trabajos era poder ser de sostén para la familia; hoy en día la compensación monetaria está relativamente baja en la lista de razones por las que uno selecciona un empleo. Hoy en día esta falta de respeto se traduciría en no poder retener empleados de calidad.

Respetar a las personas - tanto a la gerencia como a los trabajadores - es clave para permitir flexiblidad en el proceso, mejora continua del proceso, y atraer y retener personas disponibles para trabajar.

En el desarrollo de software, respetar a las personas incluye la noción de que el equipo que hace el trabajo es responsable por el proceso que siguen. El proceso se convierte en su comprensión de cómo desarrollar software mejor. Cuando esto cambia, el proceso cambia. Luego, el proceso es la base del equipo para construir software de la mejor manera que conocen, dentro de las restricciones que tienen.

Eliminar el despercidio y posponer el compromiso

Un mantra muy claro para todos los desarrolladores es minimizar la complejidad y el retrabajo. Y estamos diciendo minimizar, no elminar. Aunque no se puede evitar por completo la complejidad y el retrabajo, los principios Lean pueden ayudar a aliviar el problema.

Eliminar el despercidio es la guía principal de un practicante Lean. Existe despercidio en el esfuerzo que se requiere para construir un producto: cualquier trabajo que no agrega valor. El desperdicio es evidente en el código que es más complejo de lo necesario. El desperdicio surge cuando se crean defectos. En donde haya desperdicio, el practicante Lean observa al sistema para ver cómo eliminarlo porque es probable que cuando encontramos un error, va a continuar repitiendose (de una manera u otra), hasta que arreglamos al sistema que lo provoca.

Posponer el compromiso signifca posponer comprometerse a tomar una acción hasta que tener toda la información necesaria para tomar la decisión a la que nos comprometemos, o hasta que no podamos esperar más a tomar esa decisión sobre qué hacer. Este principio puede usarse para guiar a los requerimientos, al análisis y al diseño de un sistema.

Posponer el compromiso en los requerimientos y el análisis. Muy a menudo pensamos en los compromisos como en una acción o decisión que hicimos. Para también puede ser un compromiso a usar tiempo. Una vez que hayamos usado cierto tiempo en hacer algo, no puede deshacerse - es decir, no podemos volver atrás el tiempo. Al tomar requerimientos debemos preguntarnos - ¿en dónde debería usar mi tiempo? ¿Necesito discutir todos los requerimientos con el cliente? Claramente no. Algunos requerimientos son más importantes que otros. Debería empezar con los requerimientos que invlucran funcionalidad que es la más importante para el negocio, y por los requerimientos que crearán un riesgo técnico si no se los ataca tempranamente.

Estos requerimientos que son los más importantes para el engocio son los que usualmente le dan más valor al cliente. Los métodos Ágiles se encargan de esto al hacernos enfocar en aquellos requerimientos que el cliente siente que son los más importantes. Esta es una de las principales justificaciones del desarrollo por iteraciones. Pero como guía sobre qué trabajo hacer no es suficiente mirar a la importancia de las características según el cliente. También hay que prestar atención a los riesgos arquitectónicos. ¿Cuáles requerimientos puede provocar problemas si se los ignora? Estos requerimientos también tienen que atenderse.

Posponer el compromiso en el diseño. Los desarrolladores tienden a tomar uno o dos enfoques distintos cuando se los fuerza a diseñar algo que no tienen muy claro. Un enfoque es hacer las cosas lo más simple posible sin hacer nada para atajar a los requerimientos futuros (no confundir con la regla de Extreme Programming, que es hacer algo lo más simple posible - esta regla es dentro del contexto de otras acciones). El otro enfoque es anticiparse a lo que pueda ocurrir y construir hooks dentro del sistema. Ambos de estos enfoques tienen desafios distintos. El primero genera un código que va a ser dificil de cambiar. Esto ocurre porque no se considera la naturaleza cambiante del código cuando se lo escribe. El segundo enfoque genera código que es más complejo del necesario. Esto ocurre porque la mayoría de los desarrolladores tienen una discapacidad para ver el futuro, igual que yo (una forma de decir de que no pueden adivinar el futuro - hasta donde yo sé, todos somos discapacitados en este sentido!). Luego, cuando nos anticipamos a resolver temas futuros, a menudo terminamos con hooks (clases, métodos, etc.) que en realidad no se necesitan y agregan complejidad.

En enfoque alternativo a estos dos es el Diseño Emergente. El Diseño Emergente en el software es una combinación de tres disciplinas:

  • Usar patrones de diseño para crear arquitectura de aplicaciones que son robustas y flexibles.
  • Limitar la implementación de estos patrones a aquellas características que sean relevantes.
  • Escribir pruebas unitarias y de aceptaciónautomatizadas antes de escribir el código para mejorar el proceso de pensamiento y para crear una "red de seguridad" de pruebas.

Los patrones de diseño hacen que el código sea facil de cambiar, limitarse a escribir código para lo que se necesita hace que el sistema se mantenga pequeño (y menos complejo), y las pruebas mejoran al diseño y hacen que el cambio sea seguro. El Diseño Emergente en su conjunto permite que se pueda posponer el compromiso para una implementación en particular hasta que comprendamos lo que realmente se necesita.

Uso del desarrollo iterativo para minimizar complejidad y retrabajo

Los principales motivos de la complejidad son:

  • Escribir código que no se necesita.
  • Tener código altamente acoplado entre si.

Al hacer un desarrollo iterativo evitamos escribir código que no se necesita. Es decir, el desarrollo iterativo nos ayuda a descubrir lo que el cliente realmente necesita y nos ayuda a evitar construir algo que no sea de valor. El Diseño Emergente nos asiste en el desacoplamiento al permitirnos usar código sin agregar complejidad innecesaria al hacerlo.

Crear conocimiento

La creación de conomiento es una parte integrar del proceso Ágil. Construimos por etapas para descubrir lo que el cliente necesita. Al hacerlo de esta manera entregamos valor rápidamente y evitamos construir cosas de menos valor. Creo que el desarrollo de software es más un proceso de descubrimiento que de construcción. En este aspecto es muy parecido al desarrollo de productos.

Una definición útil del Desarrollo de Productos es que son las actividades colectivas, o sistemas, que una empresa utiliza pra convertir su tecnología e ideas en un flujo de productos que satisfacen las necesidades de los clientes y los objetivos estratégicos de la empresa (Kennedy 2003).

Más aún:

Es el producto, la actividad, el proceso en el cual se embebe el software el cual es el producto real en desarrollo. El desarrollo de software es sólo un subconjunto del proceso de desarrollo del producto. Entonces en un sentido muy real, podemos llamar al desarrollo de software como un subconjunto del desarrollo de productos. Y así, si queremos comprender el desarrollo de software Lean, haríamos bien en descubrir lo que constituye un desarrollo de producto de excelencia (Poppendieck y Poppendieck 2006).

Podemos mirar al desarrollo de producto en tres partes:

  1. Descubrir lo que necesita el cliente.
  2. Entender como construirlo.
  3. Constuirlo.

En el desarrollo de software parece que gastamos la mayor parte del tiempo hablando del Paso 3; sin embargo son los dos primeros pasos los que nos terminan llevando más tiempo. Imaginemos haber terminado un proyecto de desarrollo de software y luego, al final, perdemos todo el código fuente. Si quisieramos re-crear el sistema, ¿cuánto tiempo nos llevaría? Y por "re-crear" quiero decir reconstruirlo esencialmente de la misma manera, sin intentar mejorarlo... lo único, podemos dejar afuera cosas que no son necesarias. La mayoría de los desarrolladores diría que esto les tomaría entre un 20%-50% del tiempo que les llevó escribirlo la primera vez. Entonces, ¿qué se estuvo haciendo el otro 50%-80% del tiempo? Estuvimos "descubriendo lo que el cliente necesita" y "entendiendo cómo construir eso".

Entregar rápidamente

Otra razón para hacer desarrollo iterativo es poder entregar valor de manera rápida al cliente. Esto permite lograr una mayor penetración en el mercado, mayor credibilidad del negocio con el cliente, más lealdad y otros intangibles. Sin embargo, también genera ganancias de manera más temprana,  permitienendo que las entregas iniciales paguen al desarrollo subsiguiente.

Si bien los beneficios de entregar rápidamente son claros, es esencial que esto se haga de una manera sustentable.

Construir la calidad desde adentro

Para poder sostener la velocidad del desarrollo, los equipos tienen que construir la calidad tanto en el proceso como en su código. Construir calidad en el proceso les permite mejorarlo al eliminar los desperdicios que crea o necesita. Una mejora sugerida es juntar al cliente, a los desarrolladores y testers y definir pruebas de aceptación antes de escribir el código. Esto mejora la conversación alrededor de los requerimientos y también asiste a los desarrolladores en comprender qué funcionalidad se necesita escribir.

Construir calidad en el código se logra por los métodos mencionados anteriormente para eliminar el desperdicio. La mayoría de los desarrolladores gastan mucho tiempo descubriendo cómo arreglar errores que fueron reportados. Esto es por falta de pruebas automatizadas y por una pobre calidad de código que lo hace dificil de entender.

Optimizar el total

Uno de los cambios más grandes generados por el pensamiento Lean fue cambiar la creencia de la producción en masa de que se necesita optimizar cada paso paso, y llegar a comprender que para incrementar la eficiencia del proceso de producción se necesita mirar al flujo de valor desde el principio del ciclo de producción hasta su final. En otras palabras, hacer que cada máquina funcione lo más eficientemente posible no va a funcionar tan bien como si miráramos al flujo productivo en su totalidad. Debemos enfocarnos en el proceso completo.

El problema con optimizar cada paso es que genera inventarios grandes entre los pasos. En el mundo del software, estos "inventarios" representan al trabajo parcialmente terminado (por ejemplo, requerimientos completos, pero sin diseñar, codificar o probar). Lean demostró que un flujo de "una pieza" (por ejemplo, enfocarse en construir un ítem de manera completa) es un proceso mucho más eficiente que concentrarse en construir todas las partes más rápido.

En los artículos siguientes veremos cómo optimizar el total usando un flujo-rapido-flexible, y veremos algunas reflecciones sobre Justo A Tiempo (JIT).

La guía completa

  1. Parte 1: los principios Lean
  2. Parte 2: Lean y Ágil (este artículo)
  3. Parte 3: Justo A Tiempo y conclusión
Traducido de An Agile developer's guide to Lean software development, de Shalloway, Beaver y Trott.

Inspiración.

"Si tú tienes una manzana y yo tengo una manzana e intercambiamos las manzanas, entonces tanto tú como yo seguiremos teniendo una manzana cada uno. Pero si tú tienes una idea y yo tengo una idea, e intercambiamos las ideas, entonces ambos tendremos dos ideas"

Bernard Shaw