The topic of this story is refactoring. How can you improve your code through refactoring?
First we will define refactoring, then dive deeper into the topic with the why, when, how and the results of refactoring. That will give us an overview of the topic from a programmer’s point of view.
Definition of refactoring
Refactoring is at its core a change of the code without any changes to its external behavior. That is preserved. You restructure your code like you factor a mathematical equation. The fundamental truth about the code is unchanged, like the result of the mentioned equation.
If you like engineering then maybe you like the construction metaphor of programming. You architect your solution like a building. But any experienced professional can tell you that programming is more like gardening. Code evolves and — most importantly — decays and rots if left without any care. New technologies pop up. New requirements are desired by the biz guys. And then your handbook tells you: „Do not live with broken windows“. So you are supposed to do something about the ugly code. It is like a hygienic habit. You do it often, at best daily. Take care. Do something.
Refactoring does something nice to your code. It makes it more concise. You and your colleagues can read it easier. Its overall complexity gets reduced by a more fitting architecture or object hierarchy. The code is more expressive and extensive on the whole. So the main point is: Refactoring increases the maintainability of the project.
So you want to ask for a rewrite, because refactoring seems to be to complicated? Think twice. Your code base contains a lot of insights e.g. about corner cases and already fixed bugs. All that knowledge would get lost. And all rewriting you can do can’t fix the ugliness of the specific requirements of this particular project. You have to deal with them again. And don’t get me started about parallel maintenance of the legacy and the new app.
You refactor basically when it starts to stink. Code smells are the trigger. See them in the code, then start refactoring. But please, don’t start without a plan. Make a refactoring schedule, especially if there is a hell lot of things to be cleaned up. Track the smelling parts and then get it done piecewise. Maybe you don’t have the time to make the total cleanup now, so use the most notorious 80/20 rule. You know it. If you don’t know it, google it now. Don’t read further, use Google. You won’t regret it. Using this approach solves also the ugly problem of time pressure. Don’t let the time pressure of your everyday working life convince you to postpone needed refactoring forever.
One nice reason for refactoring: self-improvement. The things you learn from the code and your daily progress forces you to reevaluate yesterday’s code.
A final hint applicable in every project: refactor early, refactor often.
How to refactor?
To approach the topic if you are finally convinced to adhere to the campground rule: always leave it better than you found it! Basically TDD teaches us the infinite cycle of red, green, refactor. So you need tests to do refactoring in an orderly fashion. A solid (less than exactly 100% code coverage) set of automatic tests will make your refactoring maybe not 100% safe, but at least economically viable. The tests should run fast, so that they get used with any edit regardless how little has changed.
So now you make a micro refactor, check your tests and repeat. A micro refactoring is a little standardized pattern of edits, that accomplishes not much on its own, but put several of them together and now we are talking.
Micro refactorings are documented in Martin Fowlers great book about the topic. That book is the canonical reference, so read it if you thirst for knowledge. They are also supported by many IDEs that provide automated support for some of them.
A nice strategy it to refactor your code to design patterns. That means that the target structure will be a specific design pattern. See the book of the same name for further insights about that topic.
Results of refactoring
So what does refactoring result in? If we are lucky and it is done well, we will get the above stated wins and discover maybe one or more dormant bugs and/or vulnerabilities. If we do the refactoring poorly on the other hand we could introduce more bugs into our code or change unintended the external behavior of the program. But what is the downside if we don’t refactor at all? The code will decay and rot and we will accumulate more technical debt until the program isn’t maintainable any longer.
So refactor early, refactor often.
Now you have finished reading this little article about refactoring. Maybe this short essay has given you some insights and an idea on how to proceed with the upkeep of the cleanliness in your codebases.