If It Ain’t Broken, Look for What You Can Improve
You know the famous marshmallow experiment, don’t you? When faced with a tough decision some people choose the easy option, some choose the hard one. You will face some tough decisions in software development. My experience is people are not too eager to take the hard path. Especially if the subject is refactoring.
For those who are not familiar with the term; refactoring is the practise of improving the abstractions in a piece of code without changing its behaviour. Why are we making any changes if it will still have the same functionality? Because software grows. And if you don’t replace the old abstractions that were suitable for yesterday’s needs with new abstractions that will provide a better foundation to tomorrow’s needs, it will grow like a tumor.
If you are writing software eventually you will face the decision; to push forward and implement new features or to hit the brakes and refactor. If you face this decision that means the current structure is somehow incompatible with the future requirements. You look around yourself and all you see is is slums. I think you should always choose to refactor.
I read very a nice story about refactoring, or what happens when you avoid it like a disease:
“But this is madness!” cried the monk. “Now that you have some sense of how many rooms are needed, can you not tear down this monstrosity and start anew?”
“What nonsense. Imagine the time such an endeavor might take, and how displeased my master might become in the meanwhile! How could I justify subtracting storerooms instead of adding them? My exile might be extended for another decade! No, it is far safer to do exactly as I have been commanded. Anyway, I understand this hermitage quite well, its strong places and weak ones; and so long as I tread lightly and avoid pepper, my odds of perishing in a long fall are reasonably low.
This monk faces the decision and is sent by his master to see this other monk who chooses to ignore the signs of impending doom. The first monk learns his lesson when sees his peer in his miserable condition. (In case you haven’t read The Codeless Code before; the monks are analogous to programmers.)
Let’s face it, we programmers usually have strong opinions. My programming language/web framework/agile methodology is better than yours and I will defend it to the last drop of my blood. Long after you prove that my thing is rubbish, I will still be defending it with blind faith. Don’t tell me you have never done this.
Die hard anti-refactoring advocates are proud that they are not living in an ideal world. This is almost like a virtue for them. Sometimes to the extereme that they consider it a blasphemy if you suggest some changes that would make life easier. Because, well, they are not living in an ideal world and therefore there must be some suffering. And if you want to avoid this suffering that means “You want to live in an ideal world, that doesn’t exist!”
The suffering is not the only problem here. Rotting code always come with a penalty. You will pay the price one way or another. Either you will refactor as you build new features and pay the price in small installments. Or you will let entropy take over and still pay it, but with high interest. In this sense technical debt is very much like credit card debt. The difference is, in our case you can bury your head in the sand and pretend like you are as productive as you would be if you were working on a decent code base.
If my analogy above makes sense then you should have no issues with my main message; if you are between a rock and a hard place, choose to refactor first and build on a strong base instead of trying to be the hero who saves the day. It will hurt, but you will be doing the right thing.
Refactoring, from a bottom-up perspective, is about your professionalism. Do you want to take pride in your work? Then stand up and communicate that refactoring is unavoidable and some resources need to be allocated. (10% of development time, if allocated religiously every iteration, goes a long way.)
There is also a top-down, managerial component to refactoring. Management measures a team’s success with the tasks completed. So when you say “I want to do something that won’t add anything to the functionality of our software” you may not get very positive reactions. It is possible that you will be branded as someone who doesn’t understand business requirements. How dare you waste the limited resources? So the management needs to understand technical debt at least as a high level concept. Or you need to have enough autonomy to be able to make the decision yourself. Ideally both.
What happens as you accrue more and more technical debt? First good people will leave, you will be left with the mediocre coders. Then it will tip and you will go bankrupt. You will experience heisenbugs. Development speed will come to a halt. Developers and the management will be at each other’s throat.
To sum it up; when a need to refactor become apparent don’t wait to perform it. It is your professional responsibility. Even if we can never live in an ideal world, the rational thing to do is to endeavour to come closer to it.
If you have any questions, suggestions or corrections feel free to drop me a line.