Refactoring is an intrinsic part of software development. However, it seems often difficult to justify a refactoring to the Product Owner. We will see in this article how to properly justify refactoring, when it is useful but also when refactoring is a lost of time.
Why refactoring is a good thing ?
Some developer see refactoring as a failure, especially when they have to refactor their own code. A failure of having conceived a good evolutive design. A failure for having chosen the wrong architecture. But it is not the case. You have conceived a software with the vision, needs and skills your had at that time. Now you have a better vision of how things should works. Now you have new needs that you couldn’t anticipate. Now you are a better developer. Now you know what is good and what is wrong with current design, and you are ready to improve your code. So let’s state a point:
A good design is not a design that won’t need refactoring in the future. A good design is a design that will facilitate refactoring in the future.
So refactoring is mandatory to make your code follow your business, to make your code evolve in the direction you chose. Refactoring is that good friend that drive its drunk buddy until its home and avoid it being lost in the middle of the highway.
Why refactoring is seen as a lost of time ?
Let me be the devil’s advocate to see why some Product Owners may be reluctant to do refactoring. From a product point of view, refactoring don’t add any value. You begin with a set of feature and you end up with the same set of feature with the risk of breaking something.
— Yeah, but the code is cleaner !
— Customer don’t care about code.
— Yeah, but it is less buggy !
— By how much ? Do your refactoring will fix bugs we have in our database ? Which one ? We don’t care about 5 years old bugs, we care about important bugs that has been opened recently. How many bug will it fix compared to bug it will create ?
— Yeah, but future feature will be faster to implement !
— By how much ? You want to plan a 1 month refactoring. Could you ensure that future feature will take half the time to be done so that it can be profitable in 2 months ?
I think you got it. Refactoring for refactoring is pointless and risky. “The code will be cleaner” is not an argument. How can you prove that YOUR code is actually better than existing code ? And what does it mean to have a “clean code” ?
How to justify refactoring ?
Refactoring is a good practice but it should be done intelligently. You must have a reason to touch existing code and you should do it to achieve a goal. I will present below some good reasons to refactor a code:
Refactor to implement a story
Never say to your PO: “We can do a quick and dirty implementation for 2 points but this would require 5 points to do it correctly”. Your PO will understand “We can do it for 2 points or for 5 points”. Just tell him this story is 5 points, and use this time to do it properly. Remember The Boy Scout Rule: “Always leave the campground cleaner than you found it.” But keep in mind the main goal is the story, not the refactoring.
Refactor to enable more features
Sometime you really need a 10 point refactoring effort to implement a 1 point story. In this case, you should ask yourself: does this effort will enable other 1 point stories ?
If the answer is no, then is the effort worth it ? Maybe this development touch an old forgotten code that probably won’t be modified in the next 10 years. In this case, maybe it is better to do a small hack and let this code rest in peace.
But if the answer is yes, you should show to your PO what features this refactoring will make possible and not focus on the beauty and readability of the new code. PO don’t care about code.
Refactor to improve metrics
The 2 previous parts were focused on story oriented refactoring. A user story trigger addressing technical dept. But sometime, you want to rewrite a part of code just because it is really hard to maintain and you’ve had enough working in dirty code. In this case, you must show, with facts, that new code is actually better than previous one. Here is a non-exhaustive list of arguments that demonstrate a refactoring was actually useful :
- You have significantly decreased line of code.
- You have replaced custom code by well established 3rd part library or tool.
- You have removed a dependency with an annoying/unsupported 3rd part library or tool.
- You have improved code coverage (or any code quality metric).
- You have decreased build/test/packaging time.
If the only argument you have is “The code is cleaner and more readable”, then you didn’t refactor your code. You have only written different code. Not better, not worse than before. Just different. And you now are the only one who know how it works, congratulation.