In this article we will do a short introduction to refactoring. What it is, why you should do it and when. I think that refactoring is an important part of the development cycle and that every programmer should do it. Want to know why? Keep reading.
What is refactoring?
Simply put refactoring your code means changing it without changing its behaviour. You are not refactoring if you are fixing a bug. You are not refactoring if you are adding a feature. You are doing it with the only scope of improving your code. If we want to be precise we can quote Martin Fowler.
a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
You can think of refactoring the same way that a journalist thinks about editing an article for a newspaper (they still exist, don’t they?). The message of an article should already be present in the first draft (it works) but you would never publish it in the front page as is. You will do many small and big tweaks to it, make it more readable, more concise, remove typos and, generally speaking, improve it.
This can be translated almost to the letter in software development. Usually during a refactoring you will:
- Improve readability: by renaming methods and variables or other techniques
- Simplify the design: once it is working you usually have a better picture than at the start
- Eliminate duplication
One nice benefit of this it that sometimes you find and fix bugs in this process. An example that comes to mind is that sometimes duplicated code is coded in a slightly different way each time (while actually trying to do the same thing). Consolidating 10 “duplicated” methods into one could remove subtle bugs that hide in the small differences.
Why should I care?
Well, to put it simply you should care at least because it will make you deliver faster.
Refactoring is a habit and a good one to have. When you have this habit you will always work on a good piece of software that lends itself to being modified. So when your customer wants to change the logic that determines, in what states a company can be modified, you have one place to change and not 10 (real world example, this logic was written in 3 different ways and duplicated a total of 10 times).
Which is faster?
Most programmers consider the compiler the target audience. If it compiles all is good. If it works we are done. You should instead consider your fellow programmers the real target audience of your code since they are the ones that in the future will be reading what your wrote and will try to figure out what is going on. But why should you care? Well 99% percent of the times that future programmer will be you in a couple of months, when you have completely forgotten what you wrote and have to start from scratch. So why not make your life easier?
We need to refactor our code bases because, with time, software rots. It isn’t made out of anything material but its integrity is constantly attacked by multiple outside forces, to name a few:
- Quick fixes
Most of these are caused by stringent deadlines and the fact that customers can’t take a look under the hood. It is common for us programmers to incur in technical debt to meet a deadline and deliver on something urgent. But when you ask your bank for a mortgage it expects you to pay it back. Every time we do additional work on a code that owes quality we increase the interests we have to pay back because we are building on something that will have to be modified and probably doing some other hack to work around the issue.
Refactoring is paying off the technical debt.
With time the cost of doing a change in our code base tends to increase, since it usually becomes more complex with each extra feature, but if we don’t refactor the increase is compounded by our technical debt, so it approaches faster the point when any change costs so much that the software becomes immutable. This is a BIG problem for the business. It usually leads to declaring technical bankruptcy and having to start from scratch.
Developers love to start from scratch, that’s because in a greenfield project you have no debt to pay back and better yet you can take on any amount of debt for a long time. But this is a disaster, it means that you are throwing in the garbage a lot of domain knowledge and all the fixes to the bugs that we no longer remember and are bound to repeat.
Paying back your debt will prevent you from going bankrupt. Seems obvious, but have you really understood this?
When should I do it?
The quick answer is constantly.
It’s like cleaning your room, you can do it a bit each time, trying to keep it in a stable state of cleanliness, or you can do a Big Bang Operation. You let all your clothes on the bed, stuff everywhere, empty cans of beer on the floor and half empty boxes of pizza on your desk, you can keep living like this for a time, till you are no longer able to find the keys of your car or a clean pair of socks, then… you go into cleaning mode and clean for a day, you do nothing else but cleaning, and when you are finished you start again.
This isn’t a good strategy.
But I have to deliver these important features!
Well think it this way. If you went to a restaurant that served your meals 10% faster but once a month it would close for a week to clean the kitchen. Would you be a happy customer? Knowing that you can’t go to your favorite restaurant because it is closed. Knowing that probably most of the meals you have eaten there were prepared in a dirty kitchen. Did the cook even have time to wash his hands or he does it once a month?
They certainly will have bugs to squash.
I for one would prefer knowing that the kitchen is always kept clean, that the knifes are cleaned once used, that there are no stains of sauce everywhere. Maybe it will take a bit longer, but have you ever notice that, when you ask the waiter how long it will take to have the steak ready, he never answers:
It should take 10 minutes, but we can do it in 8 if we don’t clean up
The kitchen is always being cleaned up, and so should be your code base. You don’t need to schedule a special time to refactor, it is just part of the job you do and it isn’t optional.
You should do a refactoring especially when you realize that doing a change is harder than it should. Like in the example before of the states of a company I could have modified the 10 different methods, but I chose to consolidate them in just one and then do the change once. For the record two weeks later they changed again that logic and the edit was a 2 minutes thing instead of a 4 hours hunt to find again all the places I had to change.
When should I avoid it?
You shouldn’t refactor if you don’t have a working piece of code. We will go in more details in the next post on how to do your refactorings, but you should always refactor code that works so that if it stops working you have a working state to go back. If you do a big refactor on something that doesn’t even compile and you break something it will be difficult for you to realize it and fix it.
In the end remember that when doing your job you should follow the boy scout rule:
Always check a module in cleaner than when you checked it out
— Uncle Bob
Author: Maurizio Pozzobon
Maurizio has 5+ years developing solutions in the insurance industry. He is passionate about doing the right thing right, so he works in a tight loop with his clients to deliver the best solution possible.