You are likely familiar with the cost of making changes to a product but let me share with you a deeper view of elements which are affected by cost of change. The most common elements are: code and tests to verify the expected behavior, but there are also non-code artifacts: user manuals, analysis and design documents, software requirement specifications, test documents and so on. Hence, cost of change can be computed considering the following list of elements:
Cost of Change = coordination costs + transaction costs + Failure load cost
Coordination costs: the cost of getting people together to coordinate the change. For example, the cost of coordinating people to release a new patch for the current version.
Transaction costs which are the costs associated to the activity performed. For example, the cost of regression tests before releasing the product. And finally, failure load is the cost of addressing changes demanded by the customer. For example, cost of fixing a critical bug. David Anderson writes on his book about Kanban: “Demand generated by customer that might have been avoided through higher quality delivered earlier. Those activities don’t create any value”
First person who wrote about cost of change was Barry Boehm in the 80s. According to his point of view, cost of making changes in software development increase significantly overtime. Waterfall, which was the predominant methodology for developing software products at the time, was not able to handle cost properly due to the sequential process and as a result, cost of change for small projects increased up to 4 times and rocketed up to 100 times for big projects. Such extreme changes called “architecture breakers” were actually discovered once the system was in production due to scalability and performance issues. Waterfall’s is still being broadly used and its weak points are: no customer involvement since the requirements elicitation phase, no feedback from previous stages and delayed validation of assumptions (testing phase too late in the product life cycle).
Of course, software engineering has evolved and there are new frameworks, tools and programming languages. However, we have been unable to reduce its devastating effects so far. Back in 1980s, Boehm tried to minimize cost of development through delivering software in small increments. Agile and other lightweight methodologies evolved those ideas and nowadays they foster to build software making small iterative and incremental steps.
But, that’s not enough. For example, the Lean principle “last responsible moment” suggests that we should deliver features only when we have enough information to develop them. Thus, we defer the cost of making decisions as much as possible to minimize the risk of change.
As a consequence, Agile radically reduces the effect of cost of change however in many cases, this effect isn’t real due to superficial transitions to Agile. Many companies which are becoming non-perfect “Agile” companies have a lower cost of change than waterfall driven companies due to the fact that Agile promotes iterative development and fast feedback through delivering value often. Yet, they fail to complete the transformation: managers and developers aren’t willing to accept non-conventional software engineering practices to build high quality products.
Next picture depicts how cost of changes evolves for different approaches over time.
Notice that fast feedback dramatically reduces the cost of change at first, but it increases again over time if short feedback mechanisms aren’t ready to provide information about the health of the system. Such systems like test automation, unit testing or customer feedback provide invaluable data to react quickly to unintended consequences of change.
Now, it’s time to present a new topic aimed to help our teams visualize, identify, anticipate, react or mitigate the impact of this problem. Systems thinking aims to describe how the elements of a given system interact with each other and how the system as a whole is expected to perform. It’s worth mentioning that next part of the article is going to briefly cover systems thinking but I promise to keep writing about it in the future.
Next part depicts my personal view of the system and it can/must be argued / discussed with other actors who interact within the same system. The real value of this technique is to create a shared understanding and alignment from different actors.
Describing “my view” of the problem.
In order to support the explanation I want to show you how to use a simple archetype. An archetype is a template for describing patterns of behavior repeatedly found in different kind of systems.
“Fixing that backfires” describes a problem symptom. First feedback loop called balance loop is intended to fix the problem symptoms in the short term. This “quick fix” tries to eliminate the problem symptom but quickly it emerges again. More “medicine” is injected into the system but symptoms seem to be alleviated only for a short period of time. Same “solution” is tested again and again and again. On the contrary, there is a second feedback loop which describes a slow and silent degradation of the system. This harmful lack of performance is more and more catastrophic due to a delayed time of response between the “quick fix” and the unintended consequences.
Learning by Example
Let’s describe a hypothetical situation in which an important project for a company was very late in development. At first glance, project seemed to be very easy: project’s goal was to rewrite an existing application using a new technology. Besides, new requirements weren’t required which significantly reduced external sources of variation and complexity.
Deadline was coming and the team wasn’t responding according to the expectations. Product and code metrics, bug trends and data collected from static code analysis tools seemed to indicate critical quality problems. Furthermore, feedback collected during the product review meetings clearly indicated a lack of trust due to continuous crashes and instability of the system. Product owner who was continuously receiving pressure from stakeholders tried to reduce scope or negotiate a new deadline but his efforts to convince managers were fruitless. The company needed that product to guarantee its position in the market. Hopeless, the product owner shared the critical situation with the team during a meeting and shifted the main responsibility for delivering the product to the team.
Short term reaction Fix:
Team members who didn’t have a firm code of ethics naturally reacted to the pressure cutting corners in order to meet the deadline. They quickly planned to develop features without any kind of automatic testing and decided to postpone exploratory testing until the later phase. Finally they reserved a buffer of time to stabilize and to test the product before releasing.
After many hours of overtime and tireless effort, team was able to release a “stable” version.
Hey grandpa!!! Stop and keep talking about “Fixing that backfires”
As I mentioned before, the second loop usually takes more time to be noticeable and it provokes unintended effects on the system. At the moment that the team was making those decisions, they were unaware of the psychological impact on morale or motivation and the economic impact on cost of change, technical debt or maintainability index.
Ok, what should have they done?
The second balancing loop usually needs traction in the opposite direction from the balancing feedback loop. Making a route cause analysis of the problem in order to understand how the system is actually performing is a good starting point. Notice that, automated testing and continuous integration services provide invaluable information about the health of the system and provide fast feedback which dramatically reduces the cost of change.
Likewise, a bundle of actions can extend your toolbox:
- Providing training on systems thinking and archetypes like “Fixing that backfires” might help the team to avoid linear thinking* and superficial analysis of the problems.
- Bringing more visibility and transparency to the technical debt and cost of change through the use of tools like sonar cube, Jira or TFS.
- Putting more effort on agile practices mentioned in this article help reduce the cost of change.
Finally, I want to share with you some conclusions I have learnt from this writing.
- Cost of change is much more expensive than you can expect at first glance. In this book, authors explain to us how Microsoft Word came to market years late due to the same reasons described here.
- Agile methodologies allow us to reduce cost of change but superficial transitions only have a slight reduction in cost of change.
- System thinking is a branch of knowledge which allows us to share our mental views with others and to forecast how a system is expected to perform.
- Archetypes are templates used for determining patterns of behavior repeatedly found in different companies and different situations.
- Start modeling the system searching for feedback loops instead of fitting the view of the system into an existing archetype.
- Our behavior and code of ethics have dramatic effects in people around us and the products we work in. We shouldn’t underestimate team’s health, morale, motivation and the impact of our actions or inactions in our families.
- Root cause analysis of the problem (5xWhy?) and retrospectives are basic tools for learning.
*I promise to write about it in the future.
*For unknown reasons my zip file you can download here: Cost of change.zip is not permitted so rename it from .doc to .zip