Monday, February 19, 2007

Software Quality from Systems Thinking Perspective

Lately I was in several conversations about software quality, trust and office politics. It seems that the standard argument is that we should strive to write quality software, but in the real world we have to make compromises. Moreover, we (as developers) cannot assume the responsibility for technical decisions when there are higher interests at stake.

I don't want to repeat what Ryan said before. Instead, I wanted to look at the problem from a systems thinking perspective.

Code base with a low amount of technical debt is a healthy code base. It seldom happens that it's worth acquiring technical debt. It's very hard to estimate the amount of effort required to remove it, making it an incalculable risk, an uncertainty in the code base. For a longer discussion see Martin Fowler's post on technical debt.

A healthy code base allows developers working with it to provide reliable estimates about the amount of effort required to implement a feature. Also, a lesser number of unknowns in the code base gives developers ability to work at a predictable pace while maintaining quality. Better estimates and a stable rate of progress means developers are more likely to complete the stories they committed themselves to for a given iteration.

Keeping promises is a good way to gain trust; completing tasks that developers promised to deliver builds up trust with the product owner/customer team (and possibly within other parts of the company). When a product owner has a high degree of trust in the development team, she is more comfortable with leaving technical decisions in the hands of developers. This completes the circle: since developers are entrusted with the making of technical decisions, they can maintain healthy code that is high in quality.

In systems thinking this pattern is known as "Reinforcing Loop". The above example shows the loop that improves code quality and builds up trust in developers over time. Such a loop can also amplify negative changes.

In the presence of technical debt in the code base it's hard (if not impossible) for a developer to provide a reliable estimate. For the same reason a predictable rate of progress is hard to achieve - the amount of actual work is unknown. Depending on the size of the technical debt developers are likely to find it hard to deliver on their commitments. In such a situation developers will be under pressure from other developers on the team (and oftentimes the developer herself) and from the product owner (and possibly other parts of the organization) to make shortcuts (or in other words to increase the technical debt). Lack of trust in developers, and uncertainty in the amount of work required to improve quality and health of code base, will make a product owner hesitant to allocate time in the iteration for such work.

There is a concept of leverage in systems thinking - a sometimes small, well focused action that can produce significant, enduring improvements. Code health provides leverage that developers can use to bring improvements into software development process. By maintaining code health at a high level we (developers) create work conditions where developers are trusted and can continue to improve code health. By sacrificing quality we get trapped into a vicious cycle of eroding code health and vanishing trust.

1 comment:

Daniel De Aguiar, P.h.D said...

Out of curiosity, how do you define quality? One of the problems I run into is that it means different things to different people. As long as quality is defined the same way by all individuals who have something at stake in the project then I would agree that the 'Reinforcing Loop' pattern applies.

Hit Counter