Saturday, October 26, 2024

Introduction to Lean Software Development

Translated from the original article in Spanish https://www.eferro.net/2024/04/introduccion-al-lean-software.html

I discovered that embracing change (rather than resisting it), being flexible and adaptable (rather than adhering rigidly to a plan), allows me to make a significant impact on software development without experiencing constant anxiety. This discovery led me to enthusiastically adopt Agile Software Development (https://agilemanifesto.org/iso/en/manifesto.html). Over time, in this journey of continuous adaptation and improvement, the teams I’ve worked with have refined sustainable practices and discarded those that proved superfluous or unbeneficial. This process, enriched by Extreme Programming, Continuous Delivery, and especially by Lean principles, has allowed us to develop a highly effective work approach. However, in conversations with colleagues, I was surprised to discover that Lean principles and their application in software development are not widely known. Therefore, I decided to create a series of posts to share what Lean Software Development is and how we implement it in our teams.


An important clarification: I know that each context may require different approaches and that the agile/Lean approach is not the best option in certain contexts. However, since it’s the way I enjoy working, I almost automatically end up working in environments where it makes sense.

Origins of Lean Software Development

The concept of Lean Manufacturing, deeply rooted in the revolutionary Toyota Production System (TPS) of the 1950s, is a philosophy focused on maximizing value by eliminating waste. This approach not only transformed automotive manufacturing but also laid the groundwork for agile methodologies in software development.

Key Principles of the Toyota Production System:
  • Jidoka (Automation with a human touch): This principle emphasizes the importance of automation in production not only to reduce costs but also to prevent defects. It allows production to stop in case of any problem to avoid creating defective products.
  • Just-in-Time (JIT): Under this approach, each process produces only what is necessary for the next step, adopting a "pull" production process instead of "push."
  • Kaizen (Continuous Improvement): Kaizen promotes small, constant improvements in the process, facilitating continuous learning and adaptation, and enhancing the satisfaction of both customers and production participants.
These principles, along with others from TPS, focus on continuous improvement, waste elimination, and respect for the people involved in the processes.

The transition to agile software development was notably influenced by these ideals, especially regarding continuous improvement, process quality, and a workflow based on real demand rather than assumption-based production.

Historical Context and Evolution toward Agile Development:

After World War II, Japan faced severe economic constraints that made Western-style mass production unfeasible. In this context, the ideas of W. Edwards Deming on quality and continuous improvement found fertile ground. Deming, an American statistician and management consultant, emphasized quality and efficiency in production as means to rebuild the Japanese economy. These quality control principles, along with a focus on minimizing waste and maximizing efficiency, were adopted and adapted by Toyota, giving rise to TPS.
"Learning is not compulsory. Neither is survival." —W. Edwards Deming
In the early 2000s, as agile software development gained popularity, Mary and Tom Poppendieck, who had experience in Lean Manufacturing and were involved in agile software development, adapted Lean principles to software development. They published the first book in a series describing the Lean Software Development methodology (Lean Software Development: An Agile Toolkit), thus establishing a clear bridge between manufacturing practices and agile software development.

The principles of Lean Manufacturing, originating in TPS and reinforced by Deming’s influence, not only revolutionized manufacturing but also transcended industries, profoundly shaping agile software development. The adaptation of these principles to the software world by the Poppendiecks underscores the universality of continuous improvement, quality, and efficiency, demonstrating how approaches focused on waste elimination and respect for people can lead to significant innovations.

Fundamental Principles

Lean Software Development is based on seven fundamental principles aimed at eliminating waste and optimizing the development process:
  1. Eliminate Waste: Anything that doesn’t add value to the customer is considered waste and should be removed.
  2. Build Quality In: Quality should be an integral part of the development process, not an afterthought.
  3. Create Knowledge: Continuous learning and knowledge improvement are essential for software development.
  4. Defer Commitment: Make decisions as late as possible to maintain flexibility and adapt to changes.
  5. Deliver Fast: Fast delivery allows for early feedback and necessary adjustments.
  6. Respect People: A respectful and collaborative environment is essential for team success.
  7. Optimize the Whole: The development process should be considered as a whole to improve efficiency.

Benefits of Adopting Lean in Software Development

Implementing Lean in software development brings numerous advantages, including reduced costs and development time, increased product quality and customer satisfaction, as well as a more rewarding work environment for the team. Lean fosters a culture of constant improvement and adaptability, crucial aspects in times of high uncertainty and rapid market evolution.

For the first time in software development history, we have data that defines what a high-performance technology organization should look like, thanks to research conducted by the DevOps Research and Assessment (DORA) team. As detailed in the book Accelerate, the lean approach is fundamental in building and scaling technology teams and organizations.
Accelerate research

By integrating Lean Software Development, XP, or a combination of both with Lean Product Development and Lean Management, a high-impact team is formed, which also reduces stress and frustration—elements I consider as essential as the impact itself (https://www.eferro.net/2017/12/how-vs-what.html).

A brief preview of what will be covered in the series

In upcoming entries, we will detail each Lean principle, showing its practical application in the teams I work with. I will strive to share plenty of examples and explain our decision-making process.

As the various articles in the series are published, I will link them here:

  • Introduction to Lean Software Development (this article)
  • Interesting Lean Concepts for Software Development
  • Eliminate Waste in Software Development
  • Amplify Learning
  • Defer Decisions as Late as Possible
    • Defer Decisions as Late as Possible: Product Limits
    • Deferring Decisions and Working in Small Steps
  • Deliver as Fast as Possible
  • Empower the Team
  • Build Quality In
  • Optimize the Whole
  • Lean and XP - A Sustainable Approach for Agile Development
  • Other Lean-Influenced Concepts
While Lean has influenced various concepts and methods, such as DevOps, Lean Product Development, and Lean Startup, this series will focus on Lean Software Development. However, it’s worth mentioning that, at a team level, we seek to extend the application of Lean principles beyond development itself, encompassing product decisions and the management of other tasks and processes. You know, “Make the right thing, make the thing right.”

The next article will focus on explaining some Lean concepts that we will use throughout the series. Let’s keep learning and evolving together until then!

Resources:

Tuesday, October 08, 2024

Lean Software Development: Entregar lo más rápido posible

Uno de los principios fundamentales de Lean Software Development es entregar valor lo más rápido posible. Sin embargo, esto no significa simplemente aumentar el ritmo de trabajo, sino optimizar el flujo de valor, entregando con frecuencia, obteniendo feedback y usándolo para adaptarnos constantemente, mejorando así la eficiencia en la entrega de valor.

Vamos a explorar cómo lograrlo ajustando los procesos para movernos de manera eficiente y con confianza.

Velocidad y Dirección: No es sólo desarrollar más rápido

Ser más eficiente no se trata de construir más (ver The Building Fallacy), ni de estar siempre ocupados (eficiencia de recursos, ver The resource utilization trap). La velocidad, en términos físicos, tiene una dirección, y moverse rápido en la dirección equivocada es el mayor desperdicio que podemos tener (ver Eliminar desperdicios en el desarrollo). Para ir en la dirección correcta, necesitamos:

  • Entrega continua (Continous Deployment): para obtener feedback frecuente.
  • Humildad: para aceptar que no siempre sabemos lo que el cliente necesita ni cuál es la mejor solución técnica.
  • Adaptación: ajustando constantemente nuestra dirección técnica y de producto en función del feedback que recibimos.

Desarrollar rápido sin actuar ni decidir en base al feedback es correr en círculos. Nos agotamos mucho, pero no avanzamos nada. De hecho, es aún peor, porque acumulamos Coste Basal sin ningún beneficio (ver El coste basal del software).

¿Qué tan rápido es rápido?

Ir rápido, desde un punto de vista práctico, significa:

  •  Dar pasos muy pequeños en el desarrollo y la entrega (ver Desarrollando software posponiendo decisiones).
  • Asegurarse de que estos pasos duren entre unas pocas horas (segmentación técnica) y un día o día y medio (incrementos de producto).

Esto nos permite desplegar varias veces al día. Desplegar con esta frecuencia implica hacerlo bajo demanda, de forma segura y rápida. En un mundo ideal, estas entregas serían directamente al cliente final. Sin embargo, dependiendo del contexto, puede que haya entornos donde el despliegue a los clientes finales no sea posible, o solo se pueda hacer a ciertos usuarios (por ejemplo, en el desarrollo de sistemas embebidos o componentes de sistemas operativos). Estos entornos deberían ser la excepción (ver el modelo de Jocelyn Goldfin).

Hace unos 15 años, en Alea Soluciones, salíamos a producción entre tres y cinco veces por semana, lo cual no estaba mal, considerando que se trataba de sistemas instalados en los centros de datos de nuestros clientes. Posteriormente, en empresas como The Motion, Nextail y ClarityAI, todos entornos cloud multi-tenant, los equipos con los que he trabajado lograban desplegar varias veces al día.

En todos estos casos, alcanzamos esa velocidad de entrega utilizando Trunk-Based Development, TDD, Integración Continua y pairing/mob programming, es decir, aplicando prácticas de eXtreme Programming (XP).

Control y Velocidad: El Equilibrio Correcto

Tal como dijo el piloto canadiense de Fórmula 1, Gilles Villeneuve: "Si todo parece bajo control, es que no vas lo suficientemente rápido" ;)

Tener todo bajo control puede parecer ideal, pero en realidad, es una señal de que podrías ir más rápido. ¿Cuánto más rápido? Hasta que comiences a notar algunos fallos. Esta idea es clave cuando hablamos de desarrollar software a alta velocidad.

En mi experiencia, al trabajar con TBD, TDD y entrega continua, la confianza en el proceso crece y empiezas a acelerar, entregando cada vez más rápido. Inevitablemente, cometerás un error. Sin embargo, al trabajar en pequeños incrementos, el riesgo es bajo y corregir el fallo suele ser rápido. Tras corregir el error, es común que el equipo reduzca ligeramente la velocidad. 

Este ciclo de acelerar, aprender y ajustar es normal y, en mi opinión, es un signo de un equipo saludable que busca mejorar continuamente mientras mantiene un alto ritmo de entrega.

Necesidad de solidez en los pipelines de despliegue

En Lean, el flujo de valor comienza con una idea o experimento que queremos implementar o validar, y finaliza cuando hemos entregado el incremento, obtenido feedback y estamos listos para evaluarlo y decidir los próximos pasos.  

Aunque en la manufactura Lean se promueve la reducción de la variabilidad como una forma de estandarizar y optimizar el flujo, en Lean Product Development o Lean Software Development no todas las fases deben tener baja variabilidad. Por ejemplo, al inicio del flujo de valor, se requiere experimentación y creatividad para generar ideas y enfoques variados. Lo mismo ocurre al final del ciclo, cuando analizamos el feedback para decidir qué ajustes realizar.

Por otro lado, en la fase correspondiente al proceso “sistemático” de poner en producción, debemos asegurarnos de que haya mínima variabilidad. Esta etapa debe ser rápida, sólida y confiable, algo en lo que podamos confiar sin problemas.  

El objetivo es que los despliegues sean aburridos, una tarea rutinaria que se ejecute en piloto automático.

Para ello, los pipelines de despliegue deben cumplir con las siguientes características:

  • Ser rápidos (<10 minutos) y confiables.
  • Ofrecer un alto grado de confianza en la solución mediante buenos tests automáticos.
  • No permitir la existencia de tests inconsistentes (flaky tests).

Esto solo es posible si consideramos a los pipelines de despliegue como ciudadanos de primer nivel dentro de nuestro sistema, desarrollándolos y manteniéndolos con el mismo nivel de calidad que el resto del sistema.

Entrega continua (Continuous Deployment): El método más eficiente

Idealmente, los cambios que realizamos deberían desplegarse a producción de forma individual, uno detrás de otro. Esto nos permite obtener feedback rápidamente y entregar incrementos de valor de manera continua. Como mencionamos en este artículo y en algunos anteriores, esta forma de trabajar ofrece grandes ventajas:

  • Ajustamos continuamente el rumbo basado en el feedback.
  • Si cometemos un error, el impacto es bajo, ya que se trata de un cambio pequeño y es fácil recuperarnos al revertir a la versión anterior.
  • Además, entender cualquier error es más sencillo, porque el cambio que lo pudo haber causado está más acotado.

Sin embargo, desplegar no es gratis, tiene un coste asociado. Requiere inversión en:

  • Desarrollo de pipelines de despliegue automáticos.
  • Tiempo de espera cada vez que ejecutamos el pipeline.

Este coste se denomina "coste de transacción", y cuando es alto, limita la velocidad con la que podemos entregar.

Mantener bajos los costos de transacción

Lean Software Development recomienda mantener el coste de transacción lo más bajo posible. Para conseguirlo, es fundamental:

  • Invertir en pipelines de despliegue automáticos.
  • Usar pruebas automatizadas que nos permitan ir a producción directamente si los tests pasan.

Esto nos brinda la confianza necesaria para desplegar sin intervención manual y garantiza la calidad en cada entrega a producción.

En los equipos en los que he trabajado, nuestra opción por defecto es el Deployment continuo. Esto significa que cualquier cambio que subimos a la rama principal va directamente a producción. Para lograrlo, separamos el deployment del release mediante feature toggles, lo que nos permite liberar nuevas funcionalidades de forma controlada, sin que estén visibles inmediatamente para los usuarios finales.



Además, hemos logrado mantener los tiempos de ejecución de nuestros pipelines de despliegue entre 10 y 15 minutos, asegurando que el ciclo de entrega sea ágil y no interrumpa el flujo de trabajo. Si algo falla, solemos implementar un rollback automático cuando los smoke tests post-despliegue detectan un problema. Esto minimiza el impacto y asegura que podemos recuperar rápidamente el control.

Como destacan Jez Humble, Joanne Molesky y Barry O'Reilly en Lean Enterprise:

"The goal of continuous delivery is to make it safe and economic to work in small batches. This in turn leads to shorter lead times, higher quality, and lower costs."

Este enfoque nos permite trabajar con confianza en cambios pequeños, acelerar los tiempos de entrega, y reducir el riesgo y coste de errores.

Conclusiones

Para entregar valor rápidamente en Lean Software Development, es crucial optimizar el flujo de trabajo sin comprometer la calidad. La velocidad no implica trabajar más rápido sin control, sino ajustar continuamente en función del feedback, permitiendo una adaptación constante. Los equipos que siguen esta filosofía logran entregas continuas y seguras, minimizando riesgos y maximizando valor.

Los principios clave son:

  • Pasos pequeños y frecuentes: Entregar en incrementos pequeños reduce el riesgo y facilita la corrección rápida de errores.
  • Costes de transacción bajos: Invertir en pipelines de despliegue rápidos y fiables permite mantener la velocidad sin afectar la calidad.
  • Feedback continuo: Entregar rápidamente permite recibir retroalimentación constante, lo que facilita mejorar y adaptar el producto.
  • Confianza en la calidad: Con pruebas automatizadas y un flujo de entrega sólido, los equipos pueden estar seguros de que cada iteración libera un producto robusto.

En resumen, este enfoque no solo optimiza la entrega de valor, sino que también permite a los equipos operar de manera sostenible, con ajustes rápidos y minimizando el impacto de los errores.


Recursos relacionados