There is always a tension in software development between the good, slow, expensive approach and the hacky, fast, cheap one.
Somewhere between NASA-quality code on the left and barely working monstrosity on the right, professional developers have to find a pragmatic balance that delivers a working and maintainable product at a reasonable cost.
So how should we choose?
I would like to propose optimising for future speed of change. In other words, when weighing up whether or not to do something, consider whether it will make future changes quicker to make. If so, go ahead; otherwise, go the other way.
What does this mean in practice?
Consider the question of unit testing.
You could write no unit tests at all: initially the rate of writing new code is increased, but each subsequent change carries a high risk of regression. Eventually future changes become slow, dangerous or both. At the other end of the spectrum, you could unit test every method, public and private. Again, maintenance becomes expensive since you need to change the tests each time you alter the code.
So what approach would we take to minimise the time it will take to make future changes to the code we write? Perhaps unit testing only the public interface so that private methods can be refactored without needing to change the tests, but are still tested for regressions. That is indeed a typical approach.
Or how about API documentation (e.g. comments at the start of a class or method explaining what it is and how it should be used). If you are writing a closed-source API for public consumption then you may have to bite the bullet and document it in full, but what about API documentation for internal projects where fellow developers will have full access to the code?
If you write no API documentation at all, developers coming along later will have to read through all the code to understand it. If you write full documentation, explaining every parameter and documenting every potential exception that can be thrown, not only will it take you a long time to write but it will also take them time to update. Instead, how about just providing a summary and using good descriptive naming to minimise the need for long-winded explanations as comments?
There are lots of other aspects of software development where thinking about future velocity can help us to make good decisions.
In some sense there’s nothing new here: we all know that writing maintainable software is a good idea. But I think that we often don’t pay enough attention to this aspect of the craft.
Part of a developer’s skill lies in correctly making a succession of small decisions:
- Should I refactor this code?
- What is a good name for this class?
- Is pair programming efficient?
My key argument is that we will spend more effort over the lifetime of a piece of code maintaining it than we spent writing it in the first place, so it makes good economic sense to spend a little extra time up front if necessary to minimise the time it will take to make changes in future. One way to help with this, when faces with yet another decision, is to ask “Will doing this help us to make changes more quickly in future?”.