Monday, November 18, 2024

Eliminating Waste in Software Development

Translated from the original article in Spanish https://www.eferro.net/2024/04/eliminar-desperdicios-en-el-desarrollo.html

In our first post, we explored the origins and foundational principles of Lean Software Development. In the second, we introduced certain basic concepts that I’ll use throughout this series. Now, we’ll focus on the first of these principles: Eliminating waste. It’s essential to understand and reduce activities that don’t add value to optimize our development processes and increase the value we deliver to our customers.  

In this article, I’ll describe examples and practices I’ve applied in various agile teams over the years. It’s important to note that the practices and examples we mention are specific to our context, such as product development and empowered teams, and they often reinforce each other. Therefore, implementing them in isolation is not advisable. For example, starting continuous deployments without an adequate automated testing system could be more harmful than beneficial.  

Adapting Lean Manufacturing Principles to Software Development

In the original Lean Manufacturing, seven main types of waste were identified: Inventory, Extra Processing, Overproduction, Transportation, Waiting, Motion, and Defects. Mary and Tom Poppendieck, based on their extensive knowledge of Lean and software development, adapted these concepts to make them more relevant in this new context. For instance, they redefined "Inventory" as "Partially Done Work", "Extra Processing" as "Extra Process", "Overproduction" as "Extra Features", and "Transportation" as "Task Switching". They considered that the remaining types of waste retained their direct applicability to software development.

Identifying and Eliminating Waste

To eliminate waste, the first step is to train the team to identify what constitutes waste. In this regard, it’s important to:  

  • Analyze from the Customer’s Perspective: We must always ask ourselves whether an activity adds value to the customer/user and if we can eliminate it without affecting their perception.  
  • Foster a Culture of Constructive Criticism: Being critical of our actions and methods allows the team to periodically analyze its way of working to identify and eliminate waste.  
  • Consider Long-Term Impact: It’s vital to distinguish between what might seem like waste in the short term but isn’t necessarily so in the medium or long term, always keeping customer/user satisfaction in mind.  

It’s essential to classify the identified waste into two categories: those necessary for specific reasons, such as regulations or laws, and those we can completely or partially eliminate without compromising customer/user satisfaction. For the first category, we should focus on understanding the reason behind these limitations to minimize waste as much as possible. For the second, it’s crucial to take a more decisive approach, systematically working to eliminate them.  

Partially Done Work

In Lean Manufacturing, the inventory of partially completed parts is physically visible and requires organization and, at times, maintenance. In contrast, in our context, "inventory" (code, knowledge, information, analysis, etc.) is not as visible but is just as costly.

The real value for the customer or user only arises when they access the new functionality or change. Often, even at that moment, the value remains uncertain until we receive feedback. Therefore, since true value is only realized at the final stage, it is crucial to shorten the time from idea conception to delivery. In other words, we must strive to reduce work in progress and decrease lead time. As Dan North puts it, the goal is to minimize the gap between the initial idea and the user's "thank you."

These are the practices we use to eliminate partially done work:

  • Analyze/Prepare backlog work on demand: We maintain a backlog for no more than a month, and if it grows, we eliminate initiatives. If it is important, it will resurface.
  • Radical vertical slicing: Both at the product and technical levels, enabling us to deploy increments within a few hours or a day. This, of course, requires Continuous Delivery (CD).
  • Trunk-Based Development: We avoid partially done work in feature branches and the merge-related problems.
  • End-to-end management by our team: We handle deployments, validate quality, monitor the product, etc., avoiding wait times for other teams or specialists.
  • Immediate deployment of improvements: Both user improvements, which provide business feedback, and technical ones, which provide system feedback.

As shown in the team's Cumulative Flow Diagram, we maintain a minimal backlog and manage related tasks only when necessary and in the smallest possible quantity.


Additional Process: Simplification Toward Value

Aligning with the Agile Manifesto, Lean Software Development promotes measuring progress primarily by the software value delivered to the customer. In this framework, any element—such as excessive documentation, redundant processes, unnecessary meetings, or approvals—that does not directly contribute to value for the customer/user should be assessed for elimination.

Since adopting Agile principles, I have collaborated with teams to streamline our processes, discarding anything that does not generate value.

From that experience, I highlight two significant changes:

  • Transition from Scrum to Kanban: Scrum initially helped us, but we evolved toward Kanban to focus on continuous workflow. This reduced extensive meetings and planning, favoring shorter, more focused sessions, adapting to Lean’s Just-In-Time model.
  • Elimination of Estimates: We prioritize small, continuous changes, allowing us to forgo traditional estimates. We still make high-level estimates for large initiatives but with a focus on minimizing risk and unnecessary time investment.

We have found that by working in small steps and preparing only what is immediately necessary, we minimize rework (failure demand) because we do not perform "speculative" work. This significantly simplifies backlog prioritization and management, allowing us to focus on essentials and save considerable effort.

In summary: Adopting a just-in-time approach to do only what is necessary has led us to a more efficient process, with less rework and more agile backlog and priority management.


While it is impossible to eliminate all documentation or bureaucracy associated with safety regulations and certifications, it is possible to address these requirements creatively to avoid additional work. In our case, we have adopted Trunk-Based Development. Every commit or push includes co-authors and triggers a series of exhaustive tests. This methodology not only satisfies auditors but is, in fact, more effective than traditional asynchronous review methods (feature-branching + PRs) and the need for explicit approvals to move forward to production.


Functionalities and Extra Code

This, along with partially completed work, is the most significant waste we see in software development and product creation. Far too often, software developed over months ends up unused or avoided by users because it fails to meet their expectations. This is the WASTE in software development. As Mary Poppendieck said, "The biggest cause of failure in software-intensive systems is not technical failure; it's building the wrong thing."

In addition to applying Lean Software Development, we must use other techniques to truly understand our users' needs and uncover which problems are worth solving. Tools like Lean Product Management, Continuous Discovery, and Impact Mapping are essential in this process, though we won’t detail them in this series of articles.

Assuming we have identified a problem worth solving and that we have customers/users with a clear need, our goal is to solve this problem/need with the least amount of software possible and as quickly as we can. In our case, we use the following practices:
  • We adopt the Agile principle of “Simplicity—the art of maximizing the amount of work not done—is essential.”
  • We see software as a means, not an end, aiming to solve needs with as little software and technology as possible.
  • We focus on customer value, ensuring that every initiative and functionality aligns with the real needs of users.
  • We delay technical and product decisions as much as possible, increasing the chances of never having to implement them or at least not implementing them fully. We always aim for the minimum version that is sufficient.
  • We employ Outside-In TDD, which ensures we only write the minimum code necessary to implement the use case.
  • We follow the YAGNI principle (You Aren’t Gonna Need It), focusing on the functionality required now, avoiding speculative design or development.
  • When something we’ve developed stops being used or doesn’t fulfill its objective, we either remove it entirely or adapt it until it has a positive impact again.
  • We work in very small steps (<1.5-2 days), presenting new increments to users to receive quick feedback that allows us to adapt and decide on the next steps. This often lets us stop investing in an application’s functionality when it’s “good enough” for the user, thus avoiding unnecessary development.

Task Switching

Frequent task switching can significantly disrupt a team’s productivity. Each change forces the mental process to restart, delaying re-entry into the “flow” state of work. To minimize these switches, we apply several strategies:

  • Minimizing WIP: The most effective strategy to prevent frequent task switching is to reduce the team’s Work in Progress (WIP). We strive to focus on one or at most two initiatives simultaneously. Ensemble/mob programming is our preferred technique to limit WIP, as when the entire team focuses on a single task, internal interruptions are naturally eliminated.
  • Continuous and Synchronous Code Reviews: By working in ensemble/mob programming, we eliminate all task switches generated by asynchronous code reviews. See Code reviews (Synchronous and Asynchronous).
  • Vertical Slicing and Technical Slicing: By rigorously applying these techniques, we can work on truly small increments. This helps us maintain workflow continuity until completing and deploying an increment. Naturally, after each deployment, the possibility of task switching arises without the negative impact of doing so mid-increment.
  • Task Completion and Spikes: We ensure tasks can be completed from start to finish. If we see this isn’t possible, we conduct a spike (http://www.extremeprogramming.org/rules/spike.html) to eliminate uncertainty or look for other approaches that don’t require interruptions.
  • Pomodoro Technique: We use Pomodoros for periods of focused work and synchronized team breaks.
  • Quality at Every Level: High quality prevents interruptions caused by failures. We apply TDD, ensemble/mob programming, and other Extreme Programming practices to maintain it.
  • Operations/Support Rotations: For teams with support functions, we implement rotations, concentrating part of the team on emergent work and the rest on planned initiatives.

Waiting

When we analyze the product development process in depth, the most common finding is that every increment/idea/backlog item spends almost all of its time waiting. Waiting for answers to questions, waiting to analyze the problem more thoroughly, waiting for feedback on the design, waiting for architectural change approvals, waiting for certain specialists to be available, waiting for someone to approve the change, waiting for code reviews, waiting for the feature toggle to be activated, waiting to communicate the change... Waiting, waiting, waiting. Clearly, if we view the process from the customer/user's perspective, any type of waiting is simply waste.

To eliminate much of this waiting, here are some tactics that have worked for us in the past:
  • Assign the team end-to-end responsibility for going from problem definition to production and operation of the solution. If possible, even give them the freedom to find the problem worth solving. This means taking charge of product management, development, quality, deployment, and operations.  
  • Even when the team is empowered, it sometimes lacks all the necessary skills. In these cases, we need to secure collaboration from a specialist, but always try to have the specialist help us improve our skills in that area instead of solving the problem for us. This won't cover all cases, but it will ensure that in simpler cases, we don't need to call on the specialist again.  
  • On the other hand, the more multidisciplinary the team members are, the easier it will be to meet needs within the team itself. This doesn't mean everyone knows everything, but rather that we promote T-shaped skills (https://en.wikipedia.org/wiki/T-shaped_skills).  
  • On a technical level, the way to systematically eliminate most waits is to move toward Continuous Delivery (CD), which typically involves placing a lot of emphasis on agile technical practices (TDD, CI, decoupling deployment from activation, etc.) and having very high confidence in our automated testing.  
  • One of the most efficient ways (flow efficiency) is to work in mob/ensemble programming so that all the available knowledge and skills are fully dedicated to the single ongoing initiative (on which the mob/ensemble is working).  
  • There’s no point in releasing to production early if we then passively wait for customer/user feedback. It's much more efficient to seek that feedback proactively and to have instrumentation at the product and system levels to learn as quickly as possible.  

Movement  

Another of the seven basic wastes considered by Lean Manufacturing is movement. In this context, it is evident that the movements an operator must perform in a factory, whether between machines, to pick up materials, or to make inquiries, are a clear waste. In the case of Lean Software Development, the category of movement was also retained, even though in our domain, this type of waste is not as direct and obvious.

In the original book, movement refers to the effort required to access the customer, obtain domain information, carry out hand-offs between specialties (ops, QA, security), etc.

Many of the tactics used to eliminate waits are also valid for reducing the waste of movement, especially regarding hand-offs between specialties.

Additionally, to eliminate other types of movements, the following strategies have proven useful:

  • Provide the team with direct access to the customer/end user or their closest representative. A practical solution could be to take on operations responsibility, so the team is directly exposed to the complaints and needs of customers/users.  
  • Develop specific tools that allow direct and efficient access to necessary information, avoiding repeated processes (e.g., data extraction tools, observability tools, etc.).  
  • Create information radiators so that it’s easy to visualize progress or relevant information without the need to actively search for it (visual management boards, automated notifications, etc.).  

Defects  

Lastly, Lean Software Development considers defects as a significant source of waste. From my experience, I would say that defects are the second most important source of waste after performing unnecessary activities (extra features/code). Although, if you think about it, not doing what the client needs could also be considered a specific type of defect :).  

Every defect we make not only generates the waste of the time spent creating that incorrect code but also the time spent fixing it, the impact on our credibility with the client/user, and all the effort from the creation of the problem to its resolution. Therefore, it is not only important to avoid generating defects but also to find them as soon as possible, since the waste/cost associated increases exponentially the longer it takes to detect the problem.  


With this in mind, the tactics and practices we usually use to minimize this waste are:  

  • Minimizing as much as possible the code we need to develop to achieve the desired impact. As you know, less code implies fewer opportunities to make mistakes.  
  • Using Outside-In TDD, starting with acceptance tests for the use case. This, by definition, generates the minimal amount of code possible, which is also well-tested from the outset.  
  • This process does not cover all scenarios and issues, so it is also necessary to create certain end-to-end tests and have strategies for specific topics such as security analysis, load testing, performance testing, etc.  
  • Another important point is testing the third-party components we use to avoid problems when updating versions or using them in non-standard ways. See Thin Infrastructure Wrappers.  
  • With all the above points, we have a good starting point, but it is increasingly common to rely on third-party infrastructure and services (SaaS, clouds, etc.). In these cases, it is more essential than ever to use production testing tactics. After all, our clients/users don’t care what the source of the problem was; they only care about the impact it had.  

Conclusions

As can be seen in the tactics and practices we employ to minimize waste, many of them relate to having solid development practices (pair programming, TDD, BDD, continuous reviews, CD, CI, etc.) that allow us to develop sustainably. Others focus on avoiding unnecessary tasks as much as possible, concentrating on what the client truly values (which doesn’t always align with what they ask for), limiting the software to current needs, and working in very small steps so we can change direction or stop investing in something as soon as necessary.  

Working in such small steps and adapting continuously allows us to streamline the required process: we need little backlog management if we have very little in it; there’s no need to coordinate different workflows if we’re all working on the same thing at the same time; there’s no need to structure communication or handoffs with other teams if we manage them ourselves. In the end, it’s about simplifying everything as much as possible to do only what is absolutely necessary, always focusing on what truly adds value. This obviously involves constantly questioning what we do and how we do it. Just because something was useful a couple of months ago doesn’t mean it still is.  

It’s not as simple as it seems, as it requires deep engagement in our work (passion) and, at the same time, the ability to let go of what doesn’t add value (detachment). It’s about living focused on a sliding window of what adds value now, of what is useful to us in the present.  

Remember that eliminating waste is just the first step on the path to Lean Software Development. In our next post, we’ll explore how to “Amplify Learning” to ensure the excellence of our products. See you soon!  

Saturday, November 09, 2024

Interesting Lean Concepts for Software Development

Translated from the original article in Spanish https://www.eferro.net/2024/04/conceptos-lean-interesantes-para.html

In this article of our series on Lean Software Development, we will focus on exploring a series of fundamental concepts that will not only enrich our dialogue throughout the upcoming articles but also aim to spark the reader's curiosity to delve into them independently. The objective is twofold: to establish a common language for discussing Lean principles and practices in software development, while also encouraging self-guided exploration to enhance our understanding and application of these concepts in the workplace.

Value

  • Value in Lean: It is defined from the customer's perspective. Any action that meets a customer need, solves a problem, or allows us to learn about that problem or about the solution's behavior is considered valuable. It is crucial to identify and focus on activities that generate value to increase efficiency. If a software change is not deployed and released to the client, its value is zero.
  • Value Stream: Represents the entire sequence of activities necessary to deliver a product or service to the customer. In our case, the value stream spans from understanding the problem until the solution (software) is in the hands of the customer. If multiple teams are involved in this stream, it is essential to identify them and optimize the entire value stream. It is not enough to be fast in development if we cannot properly deploy the solution, or if it is not the right one. We should always focus on optimizing the entire value stream.
  • Flow: Refers to the way work moves continuously through the value stream. An optimal flow is characterized by the constant movement of work, without interruptions, blockages, or bottlenecks. The goal is to maintain a continuous and sustainable flow over time, with a special focus on improving this flow throughout the entire value stream.

Efficiency

  • Flow Efficiency: This metric measures the proportion of time that a work item is actively processed compared to the total time from start to delivery. An efficient flow seeks to minimize idle time. In other words, it evaluates the relationship between the active work time on a change and the time that change remains blocked or waiting in a queue. The goal is to minimize these inactivity periods to speed up delivery.
  • Resource Efficiency: Unlike flow efficiency, resource efficiency focuses on maximizing the utilization of available resources, such as people and machines. This approach tends to keep employees as busy as possible, which often leads to task specialization and the formation of waiting queues before each specialty. This ensures that each area (front-end, QA, back-end, operations, product) always has work. However, it may result in each change taking longer to be available to the customer, countering the goals of Lean Software Development.
  • Efficiency in Lean: While Lean recognizes both types of efficiency, it prioritizes flow efficiency because it maximizes delivery speed to the customer. This does not mean that optimizing resource efficiency is ignored, but the initial priority is the customer through flow efficiency. Additionally, since Lean places a great emphasis on waste elimination, the overall efficiency achieved is usually very high. In software development terms, we first optimize the flow to release increments in the shortest possible time (flow efficiency), and once that process is functioning sustainably, we optimize resources and people's time (resource efficiency). In upcoming articles, we will see how to optimize that continuous flow of value delivery through Continuous Delivery / CD and multidisciplinary teams. This fantastic video perfectly explains the types of efficiency in Lean.




Lean Metrics

  • Throughput: Throughput in a value stream measures how much value is generated for the customer per unit of time. In a manufacturing context, this could refer to the number of pieces or items produced by a process in a specific time unit (day, hour, etc.). In software development, it refers to each increment we deploy that the customer can start using. Maximizing throughput is crucial for increasing efficiency in value delivery.
  • Lead Time: This term refers to the total time from identifying the need for a product or service until it is delivered to the customer. Reducing lead time is essential for customer satisfaction. In Lean Software Development, it corresponds to the time from detecting a need until the solution is available to the customer.
  • Cycle Time: Measures the time it takes to complete a specific work cycle within the production process. It offers insight into internal operational performance. For software development, cycle time is measured from when we start working on an increment until it is deployed and active for the customer. The goal is to minimize cycle time to obtain feedback more frequently, which is crucial for continuous improvement. For more information on the importance of working in small batches, you can check https://www.eferro.net/2021/01/small-batches-for-win-continuous.html.

  • Work in Progress (WIP): This term refers to all work items that have been started but are not yet completed. In the context of product and software development, WIP not only includes code in a branch being worked on, but also all work and context of any increment that has not been deployed and activated for the customer. This includes items awaiting code review, security validation, or tasks that are analyzed but not yet started. Essentially, any work from which the customer has not yet benefited but that we have begun in some way. When used as a metric, it represents the number of tasks in this state.
  • WIP Limit: Refers to the restriction set on the maximum number of tasks in progress allowed in a system. This limit is crucial for maintaining focus, reducing delivery time, and improving quality, as it prevents work overload and encourages the completion of tasks before starting new ones. Setting these limits helps the team improve their way of working, focusing on delivering value to the customer rather than starting new tasks when facing blocks. Maintaining a low level of work in progress minimizes the need to switch tasks, thereby reducing the waste associated with frequent context switching.


Work Organization / Flow

  • Just-in-Time (JIT): This principle focuses on producing and delivering exactly what is needed, when it is needed, and in the required quantity. In software development, this implies performing many activities only when necessary and in small batches. In terms of development, JIT involves working in very small steps and always in response to the current need. For example, we implement a feature only when there is a real demand, or propose an architecture improvement when business or customer requirements necessitate it. Working this way is very efficient but requires flexibility in the process and good technical practices that allow agility in work.
  • Pull Processing: This approach ensures that production is based on real demand, as opposed to Push Processing, which produces according to plan. In software development, working with a Pull approach means that we start tasks only when there is a specific customer demand or when based on unvalidated business hypotheses. This improves efficiency and reduces overproduction. In contrast to the Push method, which defines a work plan and pushes tasks regardless of actual demand.


Waste

  • Muda: This Japanese term means "waste." In Lean, seven types of muda are identified that must be eliminated to optimize processes: overproduction, waiting time, transportation, over-processing, inventory, movement, and defects. In the next article in this series, we will describe the main types of waste in software product development and explore practices that help us eliminate or minimize them.
  • Muri: Refers to the Japanese concept of overload or unnecessary effort. In the Lean context, muri implies excessive pressure on employees and processes, which can lead to inefficiency and employee burnout. The goal of eliminating muri is to ensure that work and resources are optimized without overloading the system, promoting an efficient and sustainable work environment. In our teams, muri can result from excessive cognitive load or pressure to complete tasks in a Push process. In a Pull process, muri is less likely to occur, as WIP is limited and tasks are only started when capacity is available after completing another.
  • Mura: Means inconsistency or irregularity. In Lean, mura is associated with variability in production processes that leads to inefficiencies and waste. The strategy for addressing mura includes standardizing processes and leveling the workload, resulting in a more consistent and predictable workflow, thus improving efficiency and quality of service or product. However, in software development, where high variability is inherent (irregular demand, uncertainty, high complexity, unknowns, emerging needs), it is more important to embrace change and be adaptable (using agile development practices) rather than trying to avoid it.

Image used with permission from author Jose Manuel Beas

(https://jmbeas.es/presentaciones/valor-y-tipos-de-desperdicio/)

Change and Improvement

  • Kaizen: This Japanese philosophy, meaning "change for the better," is fundamental in Lean thinking. Kaizen promotes continuous improvement through small, gradual changes that, cumulatively, result in significant improvements in efficiency and customer satisfaction. It involves all levels of the organization and focuses on improving daily processes, encouraging each employee to actively suggest improvements. One way to implement this Kaizen process is through retrospectives and creating the space to implement improvements identified by the team.
  • Kaikaku: In contrast to Kaizen, Kaikaku means "radical reform." This approach seeks to implement large, disruptive changes that significantly improve performance and efficiency. It is generally initiated by company or unit management and can lead to revolutionary innovations. Although Kaikaku can result in substantial improvements, it also carries greater risks due to the magnitude of the proposed changes. It is important to note that Kaikaku does NOT refer to technical or organizational changes mandated by high-risk situations for the company's survival (technical bankruptcy, organizational chaos, production incidents, etc.).
  • A3 Thinking: This is a systematic and structured approach to problem-solving, used within the Lean methodology. A3 Thinking uses a document the size of an A3 sheet of paper to condense the problem, analysis, proposed solutions, and action plans into an integrated view. This process not only promotes critical thinking and collaboration but also improves communication among team members, allowing complex challenges to be addressed more effectively and efficiently. In my experience, A3 Thinking is a very good tool for significant changes in very small steps, especially when improvements require very detailed and continuous monitoring.

Highly Recommended Resources:

Some of the concepts described in this article, while fundamental, can be initially counterintuitive. Experience shows that they are often better understood through visual demonstrations. For this reason, I strongly recommend watching the following videos, most of which are quite short, to deepen and truly understand these principles practically:

Resource Efficiency vs Flow Efficiency

WIP Limits:

General processes / Team Work:

With these recommendations, we conclude this brief article on concepts that may be useful for understanding the rest of the articles in the Lean Software Development series.

In our next article, we will focus on Waste Elimination, one of the key principles of Lean Software Development.

See you in the next post!

Wednesday, November 06, 2024

Lean Software Delivery: Empoderar al equipo

Desde mi experiencia, un equipo de desarrollo de software realmente empoderado es aquel que tiene la capacidad de impactar de principio a fin en todo el Flujo de Valor (value stream). Este equipo, partiendo de una idea o de la identificación de un problema (incluso descubriendo el problema junto a sus usuarios), asume la responsabilidad de entregar valor a esos clientes. Este valor no se limita a crear nuevas funcionalidades, sino que también incluye proteger lo ya construido, minimizar el costo de desarrollos innecesarios y fomentar capacidades que ayuden a alcanzar los objetivos del negocio de manera eficiente y efectiva. La responsabilidad extremo a extremo implica evolución, operación y mantenimiento continuo de lo que hayan construido, tomando pleno 'ownership' de su desarrollo.

https://blackswanfarming.com/value-a-framework-for-thinking/ 

Los flujos de valor pueden dirigirse tanto a clientes externos como a otros equipos o departamentos dentro de una empresa. En Alea Soluciones mi equipo se hacia cargo del flujo de valor al cliente final (software de gestión/telefonía/tv/internet para operadores de telecomunicaciones) y el flujo de valor para herramientas que aceleraban y ayudaban a otro departamento encargado de los despliegues de redes y operación de la red física. En The Motion nuestro flujo de valor era para el usuario final de nuestro producto. Y tanto en Nextail, como actualmente en Clarity AI, mis equipos (team topologies: equipos de plataforma) son responsables de Flujos de Valor internos que tienen el objetivo de acelerar/habilitar otros equipos encargados de Flujos de Valor a nuestros clientes finales (team topologies: Stream Aligned teams). 

Por lo tanto, este empoderamiento, desde la idea hasta la entrega y el mantenimiento del valor, se realiza siempre dentro de un flujo de valor, ya sea interno o externo. En las empresas, suele haber una combinación de ambos tipos de flujos de valor.

Como bien describe John Cutler, estos son los llamados Product Teams.

https://amplitude.com/blog/journey-to-product-teams-infographic


Product Engineers / Orientación a impacto

La mentalidad y cultura que siempre he intentado promover ha sido la que ahora parece estar de moda: el pensamiento de "Product Engineers". Es decir, formar equipos que no se limiten a ejecutar tareas asignadas por un manager o por el área de Producto, sino que se conviertan en verdaderos buscadores de oportunidades, resolutores de problemas y generadores de valor. Estos equipos trabajan para, a partir de un problema identificado, o del descubrimiento de los problemas a resolver, ofrecer la mejor solución posible y evolucionando de forma progresiva mediante el feedback del usuario y del propio sistema desarrollado. Todo esto se hace siempre desde la perspectiva del cliente final, teniendo en cuenta tanto el corto como el largo plazo. Solo pensar en el corto plazo puede llevar a no proteger esa capacidad de seguir entregando valor indefinidamente con nuevas evoluciones sobre el software entregado. 

Por dar algunos ejemplos prácticos, en Alea Soluciones, todo el equipo se iba rotando para hablar con cliente, dar soporte, o tener reuniones con el CEO y los responsables de otros departamentos. Todos nos involucrábamos en entender por qué hacíamos las cosas, cual era el impacto que buscábamos, y con ese conocimiento, podíamos desarrollar de forma evolutiva las soluciones que se iban adaptando a ese impacto buscado. Esto nos permitía aprender de nuestro negocio, y cada vez dar mejores soluciones. 

En Clarity AI, dentro de los equipos de Plataforma, hemos hecho muchas entrevistas a usuarios internos, usado encuestas, desarrollos conjuntos con los equipos interesados o programas de betatesters y champions, cuando hemos desarrollado algún producto interno nuevo. También solemos hacer rotaciones para el soporte para que todo el mundo tenga contacto con el uso y las necesidades de nuestros clientes.

Como conseguir esta mentalidad

Al final se trata de conseguir moldear la cultura del equipo, que dicho a si suena fácil, pero que diría que es lo más difícil y da para multitud de libros.

En mi caso, y como estamos viendo en esta serie de articulos, el desarrollo de software lean, está orientado a conseguir esta cultura, que maximiza el valor (desde el punto de vista del cliente), minimiza el desperdicio y de forma natural se orienta el cliente.

Lo que me ha funcionado en el pasado para ayudarme a contruir este tipo de culturas ha sido:

  • Tenerlo muy en cuenta en la contratación, haciendo preguntas especificas sobre producto, impacto de lo que ha hecho en el pasado. Intentando identificar si ve el software como un medio o como un fin en si mismo.
  • También en el proceso de contratación intento identificar empatia por el usuario, y foco en la calidad y el testing, puesto que me parecen puntos muy relacionados con ese espíritu de aportar valor de forma sostenida.
  • Conseguir siempre una masa crítica de miembros que ya tengan esa mentalidad para que se pueda expandir. En algunos casos eso ha implicado tener gente temporalmente con esa experiencia o traer externos para conseguir esa masa critica.
  • Hacer trainings sobre vertical slicing, temas de producto, temas de DDD haciendo hincapié en lenguaje ubicuo, dominios, etc 
  • Coaching técnico, trainings y colaboraciones con gente que ya tienen esa mentalidad (en mi caso, he podido hacerlo con Carlos Ble, Modesto San Juan, Alfredo Casado, Xavi Gost, Aitor Sanz, Codium, etc) y tengo siempre en el radar ciertas empresas que se que pueden traer esa mentalidad por si se da la oportunidad de colaborar (Codium, 540, Leanmind, Code Sherpas, Codesai, tech93, etc). 
  • Y por último, lo que algunos consideran mi superpoder: Ser un puñetero PESAO, repitiendo todo el rato el mismo mensaje… sobre el foco en el usuario, la calidad sostenida, buscar el impacto, etc.

Equipos empoderados, el balance, y la confianza

Para que un equipo esté realmente empoderado, debe tener la capacidad de decidir en qué y cómo trabaja, siempre de forma alineada con las necesidades de la organización. Esto implica poder equilibrar adecuadamente el corto, medio y largo plazo, así como balancear cambios de comportamiento (funcionalidades) con cambios de estructura (mejoras de diseño o cambios de arquitectura).

Si el equipo no tiene esta capacidad y es un ente externo quien decide en qué deben trabajar en cada momento, sin una discusión real al respecto, lo más común es que surjan problemas como:

  • Una falta de equilibrio en las prioridades, que se traduce con el tiempo en una ralentización del equipo.
  • La acumulación de deuda técnica o una disminución en la calidad del código.
  • La incorporación de nuevas funcionalidades sin una evolución correspondiente en la arquitectura del sistema.

https://x.com/johncutlefish/status/1622093852969680896

En mi experiencia, la manera de conseguir que el equipo pueda tomar estas decisiones implica:

  • Ganarse la confianza de la organización trabajando de forma responsable y alineada con las necesidades del negocio.
  • Realizar entregas rápidas y en pasos pequeños, lo que permite mucho más fácilmente mezclar de forma continua pequeños cambios de comportamiento con cambios de estructura. De forma que el valor al usuario sea un flujo continuo, mientras protegemos la evolución y sostenibilidad del propio sistema.

Como estamos viendo en esta serie de forma natural Lean Software Development y Extreme Programming nos llevan a trabajar de estar forma (pasos pequeños, maximizando valor).

En última instancia, Lean Software Development busca crear bucles de retroalimentación positivos, donde:

  • El impacto generado en pequeños pasos refuerza la confianza de la organización.
  • Esta confianza se traduce en mayor autonomía para el equipo.
  • La autonomía permite tomar mejores decisiones y mejorar continuamente nuestra forma de trabajar (Kaizen).

Si el equipo inicialmente no está realmente empoderado, está en nuestras manos analizar la situación y proponer o implementar pequeños cambios para mejorarla. Lo más importante en este proceso es ganarse la confianza de la organización, ya que esto es lo que permite acelerar ese cambio hacia el empoderamiento. Al fin y al cabo, nadie va a dar más autonomía si el equipo no demuestra, paso a paso, que es responsable y que busca sistemáticamente lograr un impacto positivo.

Así como en Lean se crea un bucle de refuerzo positivo en el que:

  • Ganamos más autonomía, lo cual nos permite tener mayor impacto, y
  • Este impacto genera aún más autonomía para el equipo,

también existen bucle de refuerzo negativo. En este caso:

  • Si el equipo no logra entregar de manera frecuente o con la calidad necesaria, la organización confía menos en él.
  • Esa falta de confianza reduce la capacidad del equipo para tomar decisiones, disminuyendo su autonomía.
  • A su vez, esto reduce las oportunidades de mejorar la frecuencia de entrega y la calidad, perpetuando el ciclo negativo. 


Causal loop


Empoderamiento y arquitectura

Tal y como hemos comentado que un equipo esté empoderado implica que tenga responsabilidad extremo a extremo desde la idea hasta la puesta en producción y operación de las soluciones que desarrolle. Para que esto se produzca de una forma efectiva se tiene que conseguir:

  • No tener dependencias (o las mínimas) de otros equipos. Y en caso de tenerlas, que existan interfaces y reglas claras para coordinar el trabajo generando los menores bloqueos posibles.
  • Que trabajemos en un entorno y con una plataforma que nos permita de forma autónoma desplegar y operar en producción nuestras soluciones.

Por supuesto, todos sabemos que estos requisitos no es algo que nos suele venir dado sino que tenemos que invertir esfuerzo de forma consciente y continua en:

  • Eliminar dependencias con otros equipos y diseñar nuestras soluciones intentando no generar nuevas.
  • Que nuestra plataforma de desarrollo, despliegue y operación mejore de forma continua y sea robusta. Lo podríamos ver como un esfuerzo consciente en hacer que nuestro lugar de trabajo sea un sitio habitable, reconociendo al mismo tiempo que si no invertimos en ello, se degradaría continuamente.

Aquí comparto algunas prácticas concretas que me han funcionado en distintos equipos:

  • Mantener un ritmo sostenible (práctica de eXtreme Programming) y dar espacio para la mejora continua y la experimentación. Es fundamental evitar que el equipo esté siempre al límite de su capacidad, de modo que exista una cierta holgura para abordar mejoras internas o explorar nuevas ideas.
  • Aplicar los conceptos de "bounded context" de Domain-Driven Design (DDD) para dividir la arquitectura según criterios de negocio/dominio, en lugar de hacerlo por componentes técnicos.
  • Evitar equipos de QA separados y asignar la responsabilidad sobre la calidad externa al propio equipo. Es posible que haya perfiles especializados en calidad, pero la responsabilidad debe ser compartida por todo el equipo.
  • Introducir el principio de “You build it, You run it”, eliminando la necesidad de un equipo separado de operaciones. Esto fomenta que el equipo asuma la responsabilidad tanto de la creación de la solución como de su operación.
  • Invertir en observabilidad y monitorización, tanto desde la perspectiva de producto como desde el aspecto técnico, para asegurar un mejor entendimiento del rendimiento y los problemas.
  • Absorber el trabajo de otros equipos si esto permite eliminar dependencias. Esto debe hacerse considerando los conocimientos necesarios y el volumen de trabajo, pero en muchas ocasiones resulta más efectivo adquirir esos conocimientos y automatizar ciertas tareas para poder asumirlas y, así, eliminar la dependencia.
  • Trabajar en pasos pequeños (vertical slicing, automatización/optimización de pipelines de despliegue, pruebas exhaustivas, etc.), lo que facilita la entrega continua y reduce el riesgo en cada cambio.

Equipos NO empoderados

En algunos casos, la organización o la cultura de la empresa es el mayor impedimento para el empoderamiento de los equipos. Los escenarios más típicos que me he encontrado son:

  • División por especialidades y funciones: Cuando la organización se estructura en áreas separadas como frontend, backend, operaciones, QA, etc., lo cual dificulta la colaboración y el empoderamiento de los equipos.
  • Equipos como "feature factories": Aunque existen equipos multidisciplinares hasta cierto punto, a menudo se ven como simples ejecutores de las soluciones decididas desde Producto o Negocio, sin autonomía real en la toma de decisiones.
  • Equipos multidisciplinares con responsabilidades técnicas: A veces se intenta crear equipos multidisciplinares, pero sus responsabilidades se asignan en función de componentes divididos por criterios técnicos y no de negocio. Esto significa que cualquier funcionalidad requiere la coordinación de varios equipos, limitando la agilidad y la autonomía de cada uno.

Si este tipo de enfoques es el status quo en nuestra organización, no hay otra opción: debe cambiar. Afortunadamente, en nuestra industria ya existe mucho material sobre cómo organizar equipos, las ventajas e inconvenientes de cada tipo de estructura, la relación entre arquitectura de software y organización de equipos, y la gestión de equipos. En este sentido, considero interesantes conceptos como Team Topologies, los patrones estratégicos de Domain-Driven Design (DDD), la ley de Conway, el modelo de cambio de Kotter, el System Thinking o pensamiento sistémico, y los sistemas socio-técnicos.

Por experiencia, os digo que esperar a que los cambios sucedan mágicamente (spoiler: no suceden) no es buena idea. Cuando he visto la necesidad de un cambio, he sido yo mismo quien lo ha impulsado. Os sorprendería la cantidad de cosas que se pueden hacer sin pedir permiso.

Ejemplos y experiencias

Alea Soluciones

En mi experiencia en Alea Soluciones, tuvimos una autonomía prácticamente completa, no solo en cuanto a decidir en qué trabajar, sino también en cómo implementar nuestras soluciones. Coordinábamos directamente con el CEO y con los responsables de departamentos clave, y todas las decisiones sobre producto y organización recaían en nuestro equipo. Partíamos siempre de la estrategia general de la empresa, integrando el feedback continuo de nuestros clientes, tanto internos como externos. Además, nuestra metodología de trabajo era completamente nuestra, evolucionando constantemente dentro de un proceso de mejora continua. Incluso teníamos la libertad de decidir sobre la contratación de nuevos miembros del equipo, siempre dentro de los presupuestos acordados con la empresa.

Esa autonomía/empoderamiento fue completamente buscado, y para conseguirlo hicimos cosas como:

  • Ganar poco a poco la confianza del resto de la empresa mediante la entrega de soluciones de calidad que tenían un impacto significativo.
  • Asumir trabajo anteriormente de otros departamentos para poder quitar dependencias.
  • Promover la multidisciplinariedad de los miembros del equipo para evitar silos.

The Motion

En The Motion, aunque teníamos un alto nivel de empoderamiento, al inicio las funciones de producto y diseño/UX estaban separadas y trabajaban con varios meses de desfase respecto al resto del equipo. Este modelo, orientado principalmente al backend para la generación de videos publicitarios, funcionaba bien en un principio y no generaba fricciones. Sin embargo, a medida que el producto empezó a requerir interfaces de configuración y administración, este desfase comenzó a resultar problemático.

Con la evolución de la organización, incorporamos perfiles con habilidades en frontend y maquetación, con gran sensibilidad hacia el desarrollo de producto y el diseño visual. También se sumó un diseñador con experiencia en maquetación web, lo que facilitó una evolución progresiva del diseño. En la mayoría de los casos, trabajábamos en pairing entre el diseñador y un desarrollador frontend, permitiéndonos avanzar en pequeños incrementos y eliminar los retrasos iniciales. Este cambio nos dio mayor autonomía y mejor sincronización entre diseño y desarrollo.


Clarity AI

Los equipos que he creado desde que estoy en Clarity AI han nacido con la idea de responsabilidad extremo a extremo desde el principio, lo que me ha permitido disfrutar de las ventajas de equipos empoderados desde el inicio. 

Cuando me uní en 2020, ya estaba en marcha un proceso para crear equipos multidisciplinares, aunque las líneas de reporte seguían organizadas por perfiles (frontend, backend, data engineering y cloud/sistemas). Este cambio hacia equipos multidisciplinares resonaba con mi forma de pensar, y me uní al equipo de liderazgo en tecnología para acelerar esta transformación siguiendo las ideas de Team Topologies. En los meses siguientes, ajustamos las líneas de reporte, redefinimos las funciones de las guilds para que funcionaran más como comunidades de práctica y adaptamos el plan de carrera de ingeniería para alinearlo con la nueva estructura. Esta nueva forma de trabajar nos permitió soportar un crecimiento acelerado, en el que fuimos creando tanto equipos multidisciplinares alineados a flujos (stream-aligned) como de plataforma.

A día de hoy, aunque ha llevado tiempo, los equipos son muy autónomos y tienen una responsabilidad casi completa de extremo a extremo. En Clarity AI, varios de estos equipos necesitan conocimiento especializado sobre sostenibilidad, y estamos trabajando en incorporar ese conocimiento de la mejor manera posible para potenciar aún más su empoderamiento.

Además, hemos incluido en nuestros principios de ingeniería varios enfoques que refuerzan la responsabilidad extremo a extremo de los equipos: “You Build It, You Run It,” “Squad Autonomy Over Standardization,” y “Flow-Driven Product Delivery.”

Aplicación de los Principios Lean

Empoderar a los equipos no solo es una estrategia efectiva de organización, sino que también representa la esencia de los principios Lean. Al reducir aprobaciones y traspasos innecesarios, eliminamos el desperdicio, permitiendo que el equipo se enfoque en lo esencial y agilice su trabajo sin obstáculos burocráticos. Este enfoque refuerza el aprendizaje continuo, ya que el equipo puede experimentar y adaptarse rápidamente, desarrollando un conocimiento profundo y compartido de sus propios procesos y resultados. Al mismo tiempo, la autonomía facilita una toma de decisiones rápida, eliminando los cuellos de botella que suelen ralentizar el desarrollo, lo cual nos permite entregar valor de forma mucho más ágil. La calidad se convierte en una responsabilidad compartida y arraigada en el equipo, que adquiere la confianza necesaria para mantener altos estándares sin depender de revisiones externas.

Al aplicar estos principios Lean, se crea un entorno de desarrollo de software más eficiente, adaptable e innovador, que no solo acelera la entrega de valor, sino que también se adapta de manera natural al trabajo en pasos pequeños, permitiendo que la mejora continua y la excelencia técnica se conviertan en una parte inherente del trabajo diario del equipo.


Referencias y enlaces relacionados

Gracias:

Este artículo ha sido mejorado con el feedback de:

Friday, November 01, 2024

Product Engineering in the AI Era

When developing a product, we must ask ourselves what value we contribute if the roles of Engineering or Development are merely seen as implementers. What is the extent of this value contribution? Furthermore, how will this contribution change now that AI will assist us with a significant portion of this work?

Let's refer to the insightful diagram created by John Cutler, which classifies the different types of teams from Waterfall to Product teams.



It's straightforward to discuss the value each type of team contributes to the business. From a business perspective, Waterfall teams or "Agile teams capable of releasing" add limited value and are primarily optimized for software creation (not necessarily for creating impact). 

In contrast, Product Teams are designed for end-to-end impact and maximizing business value.

Considering that AI will automate a considerable amount of the more routine and specialized tasks, it's clear to see the potential impact on these teams.

Teams focused on creating impact, which view software as a means to an end, will be significantly accelerated by AI, while those that are merely "implementers" may find themselves replaced. 

In this context, the importance of product teams and product engineers becomes increasingly evident.

Why should we focus solely on technology and software, when we could instead concentrate on solving business and user problems?

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