Translated from the original article in Spanish https://www.eferro.net/2024/05/amplificar-el-aprendizaje.html
In this new article in the series on Lean Software Development, we will focus on the nature of software development and the importance of optimizing our process for continuous learning.
The Nature of Software Development
Regardless of the classic mistake we often make in the industry by comparing software development to building construction or manufacturing processes (see Construction engineering is NOT a good metaphor for software), the truth is that developing a software product is a process of adapting the solution to the user’s changing needs (or to our hypotheses about those needs). That is, it is the process of continuously evolving the software to adapt to those needs.
This evolution is continuous not only because our client’s needs evolve (strategy, business rules, processes) but also because the environment in which we operate changes constantly (SaaS, competitors, AI, evolution of devices). This evolution is part of the intrinsic nature of software since its great advantage is precisely the speed with which it can evolve and adapt. Software that is not evolving is dead software (either because no one is using it or because it has become obsolete).
design by http://www.freepik.com/ |
Unlike production and manufacturing processes, where quality is conformity to established requirements, quality in software is meeting the needs of our clients. These needs change continuously, so the software must change in turn.
Therefore, we can see that at the heart of the nature of software development lies continuous and profound learning about our clients' (changing) problem or need and about the suitability of our solution to solve that problem or need.
Lean Software Development recognizes this nature of software development and considers it necessary to amplify learning to optimize the product development process.
"A mature organization focuses on learning effectively and empowers the people who do the work to make decisions." Mary Poppendieck
Amplify Learning
Learning is the cornerstone of effective software development. In the context of Lean Software Development, this principle is elevated as a fundamental guide for continuous improvement. Recognizing that knowledge is dynamic and that learning is an ongoing process is crucial for progress in an agile development environment.
However, this learning cannot be limited to specific people or roles; it must extend to the entire team, as we want the whole team to contribute, and we have already seen that learning is part of the nature of software development.
Amplifying learning involves not only understanding what the client wants but also discerning what they do not need. This discernment is critical, as building unnecessary features or functionalities is the biggest waste in software development. Therefore, the learning process must focus on the constant clarification of the client's real needs, avoiding waste and optimizing value delivery.
"The biggest cause of failure in software-intensive systems is not technical failure; it’s building the wrong thing." Mary Poppendieck
In summary, Lean Software Development recommends:
- Recognizing continuous and constant learning as the fundamental bottleneck in software product development.
- Learning from the client’s needs and problems, also identifying what they do not need.
- Optimizing continuous learning by the entire team.
Lean Software Development suggests the following tools to enhance learning:
- Feedback loops
- Iterations
- Synchronization and integration
- Set-Based Development
Grounding the Amplification of Learning
In my 15 years of experience working with various teams, I have always considered learning a fundamental part of the nature of software development. My approach has been to foster the continuous and amplified learning promoted by Lean Software Development.
Below, I outline the tools I have used to amplify learning:
Empowered Product Teams
These teams, based on business needs and strategies, have the ability to decide which problem to solve and how to solve it. They are teams with a true product mindset, composed of Product Engineers who are not only interested in the client’s problem or need but also seek to understand it deeply and propose the best solutions.
As John Cutler aptly describes, these are known as Product Teams.
https://amplitude.com/blog/journey-to-product-teams-infographic |
These Product Teams are responsible for understanding and learning about the client’s problems, using that learning to propose the best solutions. In these teams, learning is key, and they employ product discovery practices. In our specific case, team members take turns conducting user interviews, facilitating co-creation sessions, or providing support. All these sessions provide us with insights that are shared with the rest of the team, enabling us to make decisions about the next steps.
Although I am aware of more advanced techniques than those I’ve mentioned for conducting product discovery, I’ve never put them into practice. We’ve been able to make a significant impact and achieve valuable insights without using sophisticated product discovery practices, thanks to the types of products we’ve been involved with (less visual products, sometimes internal, or aimed at technical profiles).
Feedback Loops
We use Extreme Programming (XP) as a foundation, focusing on creating the smallest and most frequent feedback loops to optimize the development process:
- Constant communication: At the mob or pair level (seconds).
- Test-Driven Development (TDD): Short test and development cycles (minutes).
- Acceptance tests: Rapid evaluation of functionalities (minutes).
- Frequent deployments: Regular implementation of improvements (hours).
- Daily planning: Reviewing and adjusting daily objectives (1 day).
http://www.extremeprogramming.org/introduction.html |
Additionally, we complement these XP feedback loops with Continuous Deployment (CD) techniques, enhancing our ability to integrate and validate changes almost instantly.
"Extreme Programming is a team style of software development... enabling that by increasing feedback loops at every possible level... so if you get great feedback then you don't have to make good decisions because you can afford to just make a decision and you'll find out." Kent Beck
These feedback loops also occur through client feedback, where we can assess whether our hypotheses about client needs and the proposed solution are achieving the desired impact.
Iterations
Although we have moved away from the traditional approach of fixed iterations, we continue optimizing continuous delivery flow. We frequently iterate on different parts of the product, always focusing on the most critical areas at any given time. For us, no feature or functionality is ever definitively complete; they are constantly evolving, and it is common to revisit previously developed elements as needed. (See https://productdeveloper.net/iterative-incremental-development/ )
Synchronization and Integration
We use Continuous Integration and Continuous Delivery practices with a Trunk-Based Development approach. This ensures that the entire team maintains a complete and integrated view of the product daily, avoiding isolated code branches that persist for days or weeks. There is only one active version on the main branch, which minimizes waste, prevents conflicts, and ensures a shared vision.
This way of working allows the entire team to share the same vision of the code (the solution) at all times and prevents an individual or part of the team from isolating themselves with a different vision (and knowledge) for days while working on a functionality branch.
Set-Based Development Design
In Lean Software Development, the term Set-Based Development designates a methodology that prioritizes keeping multiple design options open throughout the development process. This approach enables the collection of as much information as possible, not only about a specific design element but also about how all elements integrate. Contrary to the tradition of making early design decisions based on the information available at that moment, set-based development favors deferring design decisions until more complete information is available, which is crucial for the development of high-quality, flexible software.
This method is based on the reality that, in software development, interactions between different components cannot be predicted with complete certainty until they are implemented and tested. Therefore, keeping design options open and avoiding definitive decisions until more data is available results in a more effective approach for managing complex, high-quality software projects.
In my teams, the practice of keeping design options open and postponing decisions until the maximum information is obtained is an obsession. I have even created a specific workshop to practice this methodology (see Lean Workshop: Postponing Decisions). The key to working with open options lies in emphasizing simplicity (XP), fostering evolutionary design, and proceeding in very small steps that allow us to make decisions at the last responsible moment. I will delve further into this topic in a full article dedicated to it in the series.
“Simplicity, or the art of maximizing the amount of work not done, is essential.” Principle from the Agile Manifesto for Software Development
Other Useful Techniques to Amplify Learning
In our day-to-day work, we apply strategies like mob programming or pair programming with frequent pairing rotations. This facilitates the rapid dissemination of knowledge within the team and prevents the formation of information silos.
We also regularly use Extreme Programming Spikes, which are timeboxed tasks dedicated exclusively to exploring and learning about specific aspects we need to master, such as a new technique, library, or technology.
Another technique that has always worked for me to improve and amplify learning is introducing blameless postmortems, applied both to production incidents and to retrospective reviews of initiatives.
Conclusions
In summary, our approach prioritizes learning as a fundamental element, working with frequent feedback cycles, and making decisions based on what we continuously learn. This approach helps us adapt quickly and constantly improve our effectiveness and efficiency in product development.
References and Related Links
- https://productdeveloper.net/iterative-incremental-development/
- https://amplitude.com/blog/journey-to-product-teams-infographic
- https://martinfowler.com/articles/continuousIntegration.html
- https://continuousdelivery.com/
- https://martinfowler.com/articles/branching-patterns.html#Trunk-basedDevelopment
- https://community.taiga.io/t/what-is-a-spike-in-agile/1451
No comments:
Post a Comment