The “Speed vs. Quality” fallacy discussion
As a developer, I often encounter situations where I have to do quite some work because other developers left rocks in my way in the form of bad code. Over the years, I have learned to deal with this using a simple algorithm:
- Build a safety net of tests, if they are not there already or insufficient
- Improve the existing code with a disciplined technique called Refactoring
- Add the feature, guided by new tests.
By doing this, I can complete the task at hand faster than if I tried to just weave it into the mess. And I also leave the code in a better state than it was before.
But my services are expensive, and a lot of this work is avoidable. So a few days ago, when I found myself in one of those situations I sent the following tweet:
Based on some of the replies I got from both developers and non-technical folks, I feel I need to elaborate on this a bit: Some people misinterpreted the tweet as “improving code is a waste of money” and felt confirmed in their beliefs. Others understood what I wanted to say, but can’t see how well-crafted code is valuable. So let me clarify using a lot more than 140 characters.
Well-crafted code is not about aesthetics, it’s about enabling a successful business
Many people fail to understand what I mean by “well-crafted” and accuse me of “gold-plating”, being “perfectionist” or striving for “beautiful” code. I agree that there are developers doing that, but this is not what I mean.
When I talk about well-crafted code, I am only talking about providing value to the business and nothing else. I have no personal interest in this beyond the fact that I want to be a professional and provide value to my customer. It is even stated in the craftsmanship manifesto:
Not only working software, but also well-crafted software
Not only responding to change, but also steadily adding value
Not only individuals and interactions, but also a community of professionals
Not only customer collaboration, but also productive partnerships
Nowhere does the manifesto mention aesthetics. Software craftsmanship is all about enabling business success through code, in a way unprofessional practices cannot.
I also think that well-crafted code will always ship faster: Having good tests in place makes me go faster because while I code I get instant feedback when I accidentally break things. Knowing about design principles prevents me from mistakes that make the next change hard. Setting up continuous integration is very easy, and will make sure people don’t ignore the tests. Investing into a continuous deployment pipeline? Really hard to argue that that makes shipping software slower.
But what is well-crafted code anyway?
First, I seldom argue for rewriting anything. Making pragmatic decisions is part of my craft, and in most cases I prefer to improve code instead. And while it is indeed very hard to define or measure “quality”, I do have a simple benchmark for “well-crafted” code (from Sandro Mancuso, The Software Craftsman):
[In a well-crafted codebase] adding or changing features does not take longer than it used to take at the beginning of the project.
Therefore, well-crafted code is code that will allow to add value today, tomorrow and in five years. Having good tests, not doing things it doesn’t need to do, following design principles, etc. are all part for this. The opposite is code that may provide some value today, but will be very expensive to change in the future.
Building software is so slow and expensive because there are not enough developers producing well-crafted code
Some people also argue that investing in well-crafted code means shipping later, but that is just wrong: As J.B. Rainsberger points out in his brillant talk “7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development”, the complications that arise when we create software rarely are the result of a complicated business domain. Instead, accidental complication — the problems developers create by being bad at their job — dominates the cost of software development.
So the reason that changing software — be it to fix a bug or add a feature — is so slow, is not because changing software is so hard per se. It is because of the problems we create for ourselves by thinking shipping the previous feature two days earlier would really be a good idea. Often, developers do this with best intentions to improve it afterwards, but that rarely happens, because the next day a new feature will be equally urgent and important, and the crap begins to pile up.
The Technical Debt Metaphor
There is a popular metaphor to explain this to business people: Technical debt. When you allow bad code into the codebase, you are taking on debt and eventually need to pay for it. But not all technical debt is created equal, and understanding it’s origins will help to understand how professional software development can reduce it. For this, I will use Martin Fowler’s Technical Debt Quadrant. According to Fowler, there are four kinds of technical debt:
- Debt created by not understanding the value of good design and code (reckless/deliberate quadrant)
- Debt from knowingly shipping problematic solutions for good reasons and being prepared to deal with the consequences (prudent/deliberate quadrant)
- Debt created by code that is produced by inexperienced or unprofessional developers (reckless/inadvertent quadrant)
- And finally, the debt created by not knowing everything and realising that after the software is built (prudent/inadvertent quadrant)
That last one is the one you cannot prevent: Even if you hire the best developers on the market, put them into a great work environment, trust them and empower them to do their best, this will happen. Yet those developers will also be able to recognise and remove this debt if you let them. They will admit mistakes and learn from them, as any professional should.
If only the industry could reach a consensus
As a community of professional software developers we can, however, prevent the other three quadrants from becoming a threat to the business if we could finally reach a consensus on this one thing:
Well-crafted code is as crucial to a business as correct bookkeeping.
If we all agreed on this, here is what I think would happen:
- Developers would not become victims of the fallacy that just producing any code is a viable thing to do, eliminating the debt from reckless/deliberate quadrant.
- We would make better decisions on shipping bad code, taking on debt only for good reasons or when the cost of doing so is really negligible. We would keep our promises to pay it back before the interest becomes too high and we would isolate the crap and keep an eye on it, making sure our hypothesis about low interest was right. This would prevent some debt from the prudent/deliberate quadrant, and ensure most of the rest is paid back.
- We would understand that learning from each other and striving for technical excellence is crucial to the business, reducing the debt we will take on from the reckless/inadvertent quadrant.
I believe that this is a future worth creating, and I hope that more people will work towards it.
But what if the client doesn’t craft?
Just when I was about to publish this article, Chad Fowler posted this:
I agree with that post on some levels. For example, this is certainly true:
When you create software, someone somewhere wants it to perform a set of functions and has a stake in how well those functions are implemented. The definition of “well” is up to the stakeholder.
However, the stakeholder cannot judge the internal quality of the software and how that affects future changes. It is my job to say “we can ship it like this, but it has flaws that will make future changes expensive”. It is also my job to continuously improve my own craft so that the quality I deliver without spending any more time on that is as high as possible.
Chad also uses aesthetics to argue against craftsmanship:
Craft falls somewhere between commodity and art. Craft items have both subjective, aesthetic appeal and objective function.
I think the craftsmanship metaphor just doesn’t work here. Again: To me, craft has nothing to do with aesthetics. The short definition of software craftsmanship in Sandro’s book just reads:
Software craftsmanship is about professionalism in software development.
Also, I’m not with Chad where he concludes that most would want to buy commodity:
Now consider yourself as the customer here. My guess is that most of my readers, even with an appreciation of the quality of the Paul Smith suit, would be much more comfortable in the Wal-Mart pants.
Personally, I don’t buy cheap pants any more. Through experience I have learned that investing money in quality clothes is money well spent. I still wear the first expensive suit that I bought, while all the cheap pants I bought before are long gone. So if you need software that will power your business for a long time to come, I don’t think buying the cheapest is the way to go.