I’ve just been reading Phil Haack’s We’re not paid to write code post, and it happened to trip over one of my fundamental beliefs about software development and code quality.
I agree with almost the entirety of the post. As developers, we are not paid to write code, we’re paid "to ship products and deliver value". True, we’re paid primarily as people that know something about writing software, but that includes knowing what problems to tackle with custom software, when to use another piece of software and even when a non-technical solution is more appropriate.
Which brings us to a related point: shipping is a feature. Without shipping, without actually giving customers something they can use and get value from, it doesn’t matter how much or how good the code your write is. It may as well not exist.
Phil also goes on to suggest "quality isn’t just the defect count of the code. It’s also how well the code meets the business needs". Right on! There is very little point in having zero defects if it doesn’t do what the customer needs. Sure, we need to take care to control defects and risks*, but to me the quality of software can not be measured purely by a bug count.
All in agreement still? Great!
"Quality in development is important, but it has to be scaled appropriately. … The reality is we all scale the quality of our code to the needs of the product.”
Now I’m pretty sure Phil is a firm believer in software quality (some of his posts on TDD helped me get into the practice), so he’s not suggesting that we ditch quality and switch to duct tape. More that quality, like most things, is a tradeoff.
He is writing this with respect to various approaches for reducing defects (like Cleanroom Software Engineering used for developing space shuttle software), rather than with the more holistic view of quality that includes suiting business needs, and he says as much in the post.
But the message is out there: we can trade quality, and I have two major problems with this.
Semantics and convenient extrapolation
The first problem is due to the subjective nature of the term "quality". Sure, if you are talking purely in terms of defects, a rigourous, 10 year testing phase on your intranet Phone Directory application may improve quality in terms of defect count, but at the cost of making the software completely useless for that time (and probably irrelevant by the time it ships). You can probably trade off some of that "quality" by adopting a more sensible, responsible testing regime.
But how about the more holistic side of quality? What about the bit about meeting business needs? Is it meeting their needs to have an unreliable piece of software that loses the data they are relying on? How about a piece of software that is such a hack it cannot be modified to meet simple changes to their needs without a year-long re-write, during which they are losing time, money and business? I can trade off that kind of quality in favour of shipping, right? So why should I waste time keeping application and data access logic out of the UI code? Why should I bother writing unit or acceptance tests? Why should I care if this is a disgusting mess of spaghetti code if I ship?
I believe there are some elements of quality your can’t trade. The fundamentals of software development that help ensure your software is fit for purpose is one of these elements. I know Phil wasn’t suggesting that, but it seems a fairly common and convenient extrapolation when people start talking about scaling quality.
Quality means slow?
My second problem with the idea of trading quality, and probably the most harmful as it encourages the "convenient extrapolation" I talked about above, is the implication that quality is slow, and that trading it away will somehow make shipping value to customers faster and more effective.
Now it is my belief that this is wrong. The idea that doing shoddy work has any benefit to customers or timelines just doesn’t match up with my experience of developing both "just ship it" software and software with a high focus on quality.
I’m not talking about 10 year defect hunts here. I’m talking about developing software in a way that ensures quality; that ensures your software meets the needs of your customer.
Shipping with quality: What if you could have both?
This has been a key focus of the last 5+ years of my professional life: finding ways to ensure quality is built into the way I develop software. It should not be a cost; it should be the fastest and most effective way to get value into the hands of my customers. The idea that the software you ship is fit for purpose should be fundamental to producing that software.
Impossible? Do you believe sacrificing quality will always be faster than doing things "properly"?
- What if Uncle Bob is on to something when he says "the way to go fast is to go well"?
- What if doing high quality work did not add extra cost to a project?
- What if doing things "properly", instead of hacking up something to ship, did not take any longer?
- What if following SOLID design principles, writing tests, using design patterns (appropriately), dependency injection, continuous integration and TDD turned out to not be an overhead, but actually meant you could respond faster to customer needs?
- What if the higher quality of the code actually made it faster to work on, and meant you could ship sooner?
If this all sounds crazy to you, what do you think has led you to that conclusion?
What if your current choice of tools, practices or technology stack meant none of the above points were true?
Would you simply accept that it is impossible to do good work and ship? Or would you change your stack, look to other technologies or different paradigms, find or write new tools, or adopt practices that don’t punish you for trying to do your job properly?
What if this idea that quality and shipping are somehow in opposition is not an inherent property of software development? It is interesting way to challenge yourself: what can you change in the way you currently work so that quality aids shipping, rather than hinders it?