Saturday, November 30, 2024

Evolving Solutions for Maximum Impact

In Lean Software Development, the way we approach solutions defines our ability to deliver impactful results efficiently. Instead of breaking down a predefined solution into small increments, Lean encourages growing a solution incrementally in a guided direction. This is achieved through continuous feedback, ensuring the solution evolves dynamically rather than being constrained by initial assumptions.

Why Feedback Matters

Feedback is the cornerstone of this iterative approach. It often pushes us beyond the boundaries of the original solution, steering us toward unexpected yet more effective outcomes. By letting feedback guide our iterations, we move closer to what truly delivers value.

The Lean Approach to Evolution

Instead of starting with a "decided" solution and slicing it into parts:

We consider a better approach, to begin with a minimal idea, iterate based on feedback, and stop when the solution achieves the desired impact:


Focus on impact, not completion: The solution is "done" when it provides the needed results, not when every imagined feature is implemented.

This mindset shifts the focus from building a large, potentially wasteful solution to creating just what is necessary.

Benefits of Lean Evolution

  • Through this approach, teams can achieve:
  • Faster impact: Reaching results quicker by avoiding overengineering.
  • Minimal code: Writing only what is needed reduces waste.
  • Lower basal cost: Simplified solutions are easier and cheaper to maintain.


Closing Thoughts

Lean Software Development reminds us that less is more. By evolving solutions incrementally and guided by feedback, we minimize waste and maximize impact. This philosophy emphasizes efficiency, ensuring that every line of code contributes to value.

Good talks/podcasts (Nov 2024 II)

These are the best podcasts/talks I've seen/listened to recently:
  • YOW! 2019 Evolutionary Design Animated (Part1) (James Shore) [Agile, Engineering Culture, Evolutionary Design, Software Design, XP] [Duration: 00:24] (⭐⭐⭐⭐⭐) Modern software development welcomes changing requirements, even late in the process, but how can we write our software so that those changes don’t create a mess? Evolutionary design is the key. It’s a technique that emerges from Extreme Programming, the method that brought us test-driven development, merciless refactoring, and continuous integration. James Shore first encountered Extreme Programming and evolutionary design nearly 20 years ago. Initially skeptical, he’s explored its boundaries ever since. In this session, James will share what he’s learned through in-depth animations of real software projects. You’ll see how designs evolve over time and you’ll learn how and when to use evolutionary design for your own projects. Part 2: YOW! 2019 Evolutionary Design Animated (Part2)
  • 5 Reasons Your Automated Tests Fail (Dave Farley) [CI, Continuous Delivery, testing] [Duration: 00:21] This video explores the five reasons why automated tests fail, including environment, test data, version control, resource use, and system behavior. It then explains how to fix these failures by controlling the environment, isolating test data, using version control, addressing resource constraints, and designing deterministic systems
  • Product Agility Podcast: 9 Million Users from a Full Stack Product Legend An Interview with Gojko Adzic (Gojko Adzic) [Inspirational, Product, Product Discovery] [Duration: 00:50] (⭐⭐⭐⭐⭐)  This interview with Gojko Adzic, the creator of Narakeet and author of "Lizard Optimization," explores his journey in building products that reach millions of users. He shares insights on "lizard optimization," a method of leveraging unexpected user behavior for product innovation and growth, as well as the importance of aligning development with the five stages of product growth.
  • Observability & Testing in Production - with Charity Majors (Charity Majors, Luca Rossi) [Continuous Delivery, Engineering Culture, Observability, Testing in production] [Duration: 00:53] This interview with Charity Majors, CTO of Honeycomb, explores the concept of observability, particularly focusing on the differences between observability 1.0 and 2.0 and the advantages of the latter for modern software development. The conversation also touches upon the importance of testing in production, implementing an effective continuous delivery process, and embracing the changing role of software engineers in the age of AI.
  • Developer Productivity Engineering: What's in it for me? (Trisha Gee) [Developer Productivity, Devex, testing] [Duration: 01:08] This video features Trisha Gee, presenting on Developer Productivity Engineering (DPE). She explains the principles and practices of DPE and emphasizes how it can improve developer experience and efficiency.
  • Shaped by demand: the power of fluid teams (Dan North) [Agile, Lean Software Development, Management, Teams] [Duration: 00:32] Daniel Terhorst-North challenges the notion of stable, long-lived teams and presents an alternative approach called demand-led planning. He argues that by structuring teams around the demand for specific types of work, including feature delivery, discovery, Kaizen, failure demand, and business as usual, organizations can achieve greater flexibility and responsiveness to changing needs.
  • Why Scaling Agile Doesn't Work - GOTO 2015 (Jez Humble) [Agile, Continuous Delivery, Lean Software Development] [Duration: 00:51] (⭐⭐⭐⭐⭐) Jez Humble examines the common pitfalls of scaling Agile methodologies and presents alternative strategies for achieving organizational agility. He argues that simply implementing Agile practices without addressing underlying systemic issues, such as lengthy feedback loops and inefficient decision-making processes, will not lead to significant improvements. Instead, he proposes that organizations focus on creating rapid feedback loops, reducing batch sizes, and adopting an experimental approach to product development and process improvement, emphasizing value over cost and estimation.
Reminder: All of these talks are interesting, even just listening to them.

Related:

Sunday, November 24, 2024

Good talks/podcasts (Nov 2024 I)

These are the best podcasts/talks I've seen/listened to recently:
  • YOW! 2019 Evolutionary Design Animated (Part1) (James Shore) [Agile, Engineering Culture, Evolutionary Design, Software Design, XP] [Duration: 00:24] (⭐⭐⭐⭐⭐) Modern software development welcomes changing requirements, even late in the process, but how can we write our software so that those changes don’t create a mess? Evolutionary design is the key. It’s a technique that emerges from Extreme Programming, the method that brought us test-driven development, merciless refactoring, and continuous integration. James Shore first encountered Extreme Programming and evolutionary design nearly 20 years ago. Initially skeptical, he’s explored its boundaries ever since. In this session, James will share what he’s learned through in-depth animations of real software projects. You’ll see how designs evolve over time and you’ll learn how and when to use evolutionary design for your own projects.
  • Working Effectively with Legacy Code • Michael Feathers & Christian Clausen • GOTO 2023 (Michael Feathers, Christian Clausen) [AI, Legacy code, Refactoring, testing] [Duration: 00:45] This interview with Michael Feathers, author of "Working Effectively with Legacy Code," explores practical strategies for managing and improving large, untested codebases, including techniques for testing, refactoring, and understanding software change mechanics. Feathers and interviewer Christian Clausen also discuss the impact of AI on code quality, the challenges of advocating for testing in organizations, and the importance of prioritizing efforts based on code value and criticality
  • Living Domain Model: Continuous Refactoring to Accelerate Delivery (Younes Zeriahi) [Legacy code, Refactoring, Technical Practices] [Duration: 00:47] (⭐⭐⭐⭐⭐) Useful talk for anyway working with legacy complex systems. Younes Zeriahi shares practical examples and techniques for refactoring code in a way that accelerates delivery and improves the overall design, using concepts like Mikado, expand and contract, and Chesterton's Fence. He also highlights the importance of a strong test suite and a deep understanding of the domain for effective refactoring.
  • Product management theater (Marty Cagan, Lenny Rachitsky) [Product, Product Discovery, Product Leadership] [Duration: 01:25] This podcast episode features a conversation with Marty Cagan about the state of product management and the differences between effective and ineffective practices. Cagan discusses the common problem of "product management theater," where individuals hold product management titles but lack the necessary skills and operate within feature teams rather than empowered product teams. The discussion emphasizes the importance of focusing on outcomes, understanding customer needs, and embracing experimentation to build successful products.
  • The Logic of Flow: Some Indispensable Concepts (Donald Reinertsen) [Lean Product Management, Product] [Duration: 00:33] (⭐⭐⭐⭐⭐) This talk explores key concepts and mathematical principles behind achieving flow in processes, like product development, drawing parallels to flow dynamics in traffic and internet systems. Don Reinertsen explains the economics of queuing, batch size reduction, and fast feedback loops, highlighting their impact on cycle time and overall process efficiency.
  • If Russ Ackoff had given a TED Talk... (Beyond continuous improvement) (Russ Ackoff) [Quality, Resilience, Systems Thinking] [Duration: 00:12] This talk explores how to avoid common pitfalls in quality improvement programs by applying systems thinking principles, arguing that focusing on improving individual parts in isolation can be detrimental to the overall system's performance.
  • Small Batches podcast: The Mental Model (Adam Hawkins) [Lean, Lean Software Development] [Duration: 00:07] This episode explores when to apply the lean mental model in software development, emphasizing its effectiveness for navigating situations with high uncertainty and the need for rapid learning.
Reminder: All of these talks are interesting, even just listening to them.

Related:

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: