Sporadically delivered thoughts on Continuous Delivery

Quality Plus Simplicity - the Sweet Spot

| Comments

There is a common belief in the software development world that a tradeoff exists between speed of delivery and quality, an idea Martin Fowler calls the Tradable Quality Hypothesis. It’s the idea that, in a pinch, you can speed up software delivery by not worrying so much about quality.

As Martin points out, people have different understanding of what quality means, but the definition that counts from a delivery point of view is that it’s the attributes that make the software easier to maintain and extend. Developers can work more quickly on code that is easy to understand and free from bugs.

So in practice, teams that prioritize speed over quality tend to achieve neither, while teams that prioritize quality, in many cases, deliver code very quickly.

The complexity axis

However, this isn’t always the case. Some teams focus on quality, but end up taking forever to deliver simple things. What’s missing from the speed vs. quality tradeoff is a second axis, completeness versus simplicity.

quadrant showing quality vs. speed and completeness vs. simplicity

Another word for completeness on this chart would be complexity, but this quadrant represents the aspirations of a team - what the team is trying to achieve - and no team aspires to complexity. Instead, teams try to design and implement software and systems which are complete.

A team that prioritizes completeness wants a system that can cope with anything. It can meet completely new requirements through configuration rather than code, easily scale to handle any load, and tolerate any conceivable or inconceivable failure.

The problem with this is partly described by the YAGNI principle. Most of what the team built isn’t actually going to be needed. A large proportion of the stuff that will be needed in the future is stuff that the team didn’t anticipate. But the real killer is that adding all this stuff adds more moving parts. It’s more stuff to implement, more stuff to go break, and then it’s more stuff to wade through when working on the codebase.

the original quadrant with an arrow showing the slide from quality + completeness to speed-focused

So the team sets out to build the perfect, well-engineered system, but over time the schedule comes under pressure, and the team realizes it needs to step up the pace. Elements of the design are dropped, leaving parts of the system that were already implemented unused, but still taking up space (and adding complexity) in the codebase.

There is a nearly inevitable slide into cutting corners in order to get things done, and before you know it, you’re trading off quality (“we’ll go back and clean it up later”) for speed. As we’ve seen, this leads to a quagmire of poor code quality which slows work down, made even worse because of an overcomplicated design and large amounts of unnecessary code.

High performing teams hit the sweet spot

the original quadrant with an arrow showing the slide from quality + completeness to speed-focused

What seems to unite high performing development teams is an obsessive focus on both quality and simplicity. Implement the simplest thing that will satisfy the actual, proven need, and implement it well. Make sure it’s clean, easy to understand, and correct. If something is wrong with it, fix it immediately.

There’s a line to tread here. I’ve seen some teams interpret this too strictly, and delivering software that works correctly and is simple, but is crappy in terms of user experience. The definition of quality software must include doing an excellent job of satisfying the user’s needs, while being ruthless about limiting the needs it tries to satisfy.

Teams that get this focus right are able to reliably deliver high quality software remarkably fast.