I’ve been crafting software for a while now so I’ve had the opportunity to see about a dozen software companies from the inside. Over the years I’ve learned some things about managing software quality that I’d like to share. I’ve distilled them into four simple rules:
- Define quality
- Manage causes, not effects
- Do not treat quality as a separate activity
- Apply standards consistently
What is Quality?If a friend tells you that his New Year’s resolution is to “get healthier”, he probably has something specific in mind, such as losing weight, gaining more energy or treating a specific health condition. Like health, quality is a very broad term and so you have to get to specifics before any actionable change can take place.
When people talk about software quality, sometimes they are thinking of a particular non-functional requirement like reliability or performance. Consider this incident from the New Horizons mission to Pluto:
That preparation paid off just before the flyby. On July 4, while attempting to process commands sent from home and compress stored science data at the same time, the spacecraft’s main computer overloaded and, as designed, switched to its backup processor. This put New Horizons into a “safe mode” where it stopped performing science, pointed to Earth and quietly awaited word from operators on the next move.
The recovery was fast and thorough; mission engineers immediately identified the problem and reestablished contact within two hours. By July 7, the intricate set of flyby commands — the critical directions for New Horizons’ science instruments — was reloaded and ready to go.
That’s a great example of fault tolerance, which might be what someone has in mind if they say they want to increase the quality of a product. If, in the process of clarifying what exactly is meant by quality, you end up landing on a non-functional requirement, that is very good news. First of all, non-functional requirements are often measurable, and secondly, it allows you to peel off and focus on just one piece of the problem, as Fred Armisen Stephen Dubner exhorts us to do in Think Small to Solve Big Problems.
Recently I was perusing the original wiki and I came across a discussion on internal and external quality. Mulling over this a bit, I eventually came to the conclusion that when software quality is discussed, it generally means one of two things:
- non-functional requirements, which we’ve already touched on
- code that is easy to change without unintended consequences
A good reason to focus on resilience to change is that this is a constant across all software systems. Non-functional requirements are subject to change from product to product. You would hope that banking software would have stronger security requirements than social media software. Non-functional requirements are also not necessarily meant to be applied to all parts of the system. For example, prematurely optimizing for performance is an anti-pattern, so it’s often best to not think about performance until you have evidence that the code is, in fact, slow. In contrast, practically all code that is written gets touched again later multiple times, meaning resilience to change is a property that all software needs, no matter the industry, and no matter if it’s a small side project or a multi-million-dollar web app.
So with that in mind, quality code is all about being able to change the software without accidentally breaking other parts of the system or being pulled into an infinite series of yak-shaving refactors.
I hope this blog post has given you something good to think about! If you wish to read more, this post is part of a four-part series on software quality: