We don’t have time for software design
Yes, that is a common argument I’ve heard pretty much everywhere as soon as I’ve mentioned the need for refactoring code in the name of maintainability. And it’s not only come from non-technical people, it has also been a prevalent thought amongst other software developers. And they’re usually adamant about it, so I thought I could dedicate a whole blog post discussing this topic.
Spending time refactoring code doesn’t provide any value to the customer
That is true, it doesn’t. At least in the short-term. However, if you’ve read my article about technical debt, I talked about what happens when you leave bad code to rot for all eternity. In the long run, as our technical debt grows, it gets even harder and harder to add something new to our software. It hinders our ability to deliver quality software to our customer. It also slows us down profusely, causing us to delay certain features. Some features may not even become feasible to implement. It may also compromise on the user experience of our software, as bugs appear and we take shortcuts when implementing things in the GUI, for example.
Continuously refactoring our code is a must if we are to provide the customer with quality software for a longer period of time. It is also required in order to remain competitive on the market, as we want to deliver new features at a steady pace and not fall behind because of unhappy customers and battling with technical debt. Last but not least, it increases the return on investment of the whole project.
So yes, in the short-term it may not necessarily provide any value (depending on the situation, of course). But the customer will see the effects of our technical debt eventually, so it does provide value in the long-term.
We must work at a fast pace, we can’t waste time designing things
This argument is fairly common, and to be honest, I don’t understand the reasoning behind this argument. Working at a fast pace is the whole point of caring about the quality of our code. Apparently we do not have time for design, but we certainly have time for brawling with bugs and trying to understand the vile depths of code no sane human has ever dared venture into. Or in some cases, rewriting the whole program.
Writing good code doesn’t have to take more time than writing bad code. Indeed, what takes time writing good code is learning how to do it. Sure, it may impose some extra time in some cases, because you have to consider the impact on the maintainability of our software when you design your solution as well. Usually this extra time is justified however, because the time maintaining the bad solution will completely outweigh the extra time it took implementing and maintaining a more maintainable design. Of course, in some cases one might think too much about how to eliminate a particular design deficiency, and in those cases you have to ask yourself: “Is this design deficiency really that bad? Does it justify the time I am spending on trying to eliminate it?” It’s all about weighing benefit and cost against each other. And it certainly isn’t easy; practice makes perfect. Be pragmatic about it. 😉
Design is an iterative process. Writing good code doesn’t mean “go to the whiteboard and design every detail, then implement it”. That never goes as planned. I have tried it, many others have tried it; it usually doesn’t work. You will just overlook many problems that will arise during implementation. Instead, you should refactor your code as you go. Test-driven development supports this idea of developing software, for example.
Doing some up-front design isn’t bad (it’s usually necessary), but keep it at a high level just to get an idea of how you’re going to solve the problem.
Nor does good code mean “Slap design patterns all over the damn thing, son.” Design patterns just happens to be common solutions to common problems in a particular context. Design patterns deserves a post of its own, so I won’t continue discussing this right now.
In conclusion, I think caring about the maintainability of our code is important. But we should also remember that the tools and techniques we use in the name of maintainability in some cases will result in a higher cost than what we benefit from, and we should learn how to identify such situations.
TL;DR: Interest on technical debt is the reason why we should value the maintainability of our software.
What technical debt is and why you should care