This post lists the key insights from this article, by Martin Fowler, chief of scientists at ThoughtWork.
A common debate in software development projects is between spending time on improving the quality of the software versus concentrating on releasing more valuable features. Usually the pressure to deliver functionality dominates the discussion, leading many developers to complain that they don’t have time to work on architecture and code quality.
Software quality means many things
Here lies the first complication – there are many things that can count as quality for software.
- You can consider the user-interface: does it easily lead me through the tasks you need to do, making me more efficient and removing frustrations?
- You can consider its reliability: does it contain defects that cause errors and frustration?
- Another aspect is its architecture: is the source code divided into clear modules, so that programmers can easily find and understand which bit of the code they need to work on this week?
These three examples of quality are not an exhaustive list, but they are enough to illustrate an important point. If I’m a customer, or user, of the software, I don’t appreciate some of the things we’d refer to as quality. A user can tell if the user-interface is good. An executive can tell if the software is making her staff more efficient at their work. Users and customers will notice defects, particularly should they corrupt data or render the system inoperative for a while. But customers and users cannot perceive the architecture of the software.
You can thus divide software quality attributes into external (such as the UI and defects) and internal (architecture). The distinction is that users and customers can see what makes a software product have high external quality, but cannot tell the difference between higher or lower internal quality.
At first glance, internal quality does not matter to customers
Since a customer never sees this source code, and it doesn’t affect the operation of the app, why would anyone pay an extra $4 for Rebecca’s software? Put more generally this should mean that it isn’t worth paying more money for higher internal quality.
Internal quality makes it easier to enhance software
So why is it that software developers make an issue out of internal quality? When I want to add a new feature to the software, my first task is to figure out how this feature fits into the flow of the existing application. I then need to change that flow to let my feature fit in. I often need to use data that’s already in the application, so I need to understand what the data represents, how it relates to the data around it, and what data I may need to add for my new feature.
All of this is about me understanding the existing code. But it’s very easy for software to be hard to understand. Logic can get tangled, the data can be hard to follow, the names used to refer to things may have made sense to Tony six months ago, but are as mysterious to me as his reasons for leaving the company. All of these are forms of what developers refer to as cruft – the difference between the current code and how it would ideally be.
A common metaphor for cruft is Technical Debt. The extra cost on adding features is like paying interest. Cleaning up the cruft is like paying down the principal. While it’s a helpful metaphor, it does encourage many to believe cruft is much easier to measure and control than it is in practice.
One of the primary features of internal quality is making it easier for me to figure out how the application works so I can see how to add things.
Customers do care that new features come quickly
Here we see a clue of why internal quality does matter to users and customers. Better internal quality makes adding new features easier, therefore quicker and cheaper.
Visualizing the impact of internal quality
The fundamental role of internal quality is that it lowers the cost of future change. But there is some extra effort required to write good software, which does impose some cost in the short term.
A way of visualizing this is with the following pseudo-graph, where the cumulative functionality of software versus the time (and thus cost) to produce it is plotted. For most software efforts, the curve looks something like this.
The subtlety here is that there is a period where the low internal quality is more productive than the high track. During this time there is some kind of trade-off between quality and cost. The question, of course, is: how long is that period before the lines cross?
The way you can assess where lines cross is by canvassing the opinion of skilled developers that you know. And the answer surprises a lot of folks. Developers find poor quality code significantly slows them down within a few weeks. So there’s not much runway where the trade-off between internal quality and cost applies. Even small software efforts benefit from attention to good software practices, certainly something I can attest from my experience.
Even the best teams create cruft
Many non-developers tend to think of cruft as something that only occurs when development teams are careless and make errors, but even the finest teams will inevitably create some cruft as they work.
Many people, including more than a few in the software industry, liken building software to constructing cathedrals or skyscrapers – after all why do we use “architect” for senior programmers? But building software exists in a world of uncertainty unknown to the physical world. Software’s customers have only a rough idea of what features they need in a product and learn more as the software is built – particularly once early versions are released to their users. The building blocks of software development – languages, libraries, and platforms – change significantly every few years. The equivalent in the physical world would be that customers usually add new floors and change the floor-plan once half the building is built and occupied, while the fundamental properties of concrete change every other year.
Dora studies on elite teams
Software projects are always creating something novel. We hardly ever find ourselves working on a well-understood problem that’s been solved before. Naturally we learn most about the problem as we’re building the solution, so it’s common for me to hear that teams only really best understand what the architecture of their software should be after they’ve spent a year or so building it. Even the best teams will have cruft in their software.
The difference is that the best teams both create much less cruft but also remove enough of the cruft they do create that they can continue to add features quickly. They spend time creating automated tests so that they can surface problems quickly and spend less time removing bugs. They refactor frequently so that they can remove cruft before it builds up enough to get in the way. Continuous integration minimizes cruft building up due to team members working at cross-purposes. A common metaphor is that it’s like cleaning up work surfaces and equipment in the kitchen. You can’t not make things dirty when you cook, but if you don’t clean things quickly, muck dries up, is harder to remove, and all the dirty stuff gets in the way of cooking the next dish.
High quality software is cheaper to produce
Summing all of this up:
- Neglecting internal quality leads to rapid build up of cruft
- This cruft slows down feature development
- Even a great team produces cruft, but by keeping internal quality high, is able to keep it under control
- High internal quality keeps cruft to a minimum, allowing a team to add features with less effort, time, and cost.
Sadly, software developers usually don’t do a good job of explaining this situation. Developers often justify attention to quality by justifying through the need for proper professionalism. But this moralistic argument implies that this quality comes at a cost – dooming their argument. The annoying thing is that the resulting crufty code both makes developers’ lives harder, and costs the customer money. When thinking about internal quality, you should stress that we should only approach it as an economic argument. High internal quality reduces the cost of future features, meaning that putting the time into writing good code actually reduces cost.
This is why the question that heads this article misses the point. The “cost” of high internal quality software is negative. The usual trade-off between cost and quality, one that we are used to for most decisions in our life, does not make sense with the internal quality of software. (It does for external quality, such as a carefully crafted user-experience.) Because the relationship between cost and internal quality is an unusual and counter-intuitive relationship, it’s usually hard to absorb. But understanding it is critical to developing software at maximum efficiency.