Given that there’s more code that could be refactored than our industry can handle, we have to decide what code should be refactored and what code doesn’t need it. If production software works fine and doesn’t need to be extended then there’s no need to refactor the code. Refactoring code is risky and expensive so we want to make sure the ends justify the means. Here are seven strategies for when to refactor code.
1. When critical code is not well maintained
Most software is in a state that makes it unsafe to refactor. If code is in production and working then touching it, even in seemingly minor ways, can break it in unexpected ways. For this reason, it’s often wise not to touch legacy code. But there are times when critical code is not well understood and it becomes enough of a liability to warrant a clean up effort. In these cases, retrofitting tests to support more complex refactoring can be useful.
2. When the only person who understands the code is becoming unavailable
We want the software we write to be easy for anyone on the team to work with but sometimes existing code has “experts” who are the only people who can work with it. This is not a good place for a company to be so if the code needs to be maintained or updated then it can be cost effective to have the key person spend time to clean up the code before moving on to avoid larger costs of cleaning it up later.
3. When new information reveals a better design
Requirements, and our understanding of them, are constantly changing. When we see the opportunity for a better design, and the benefits outweigh the costs, then refactoring code can be a good option. This is an ongoing process that helps keep software clean and up-to-date. Improving design through a series of refactorings can be a safe and an effective way to keep software maintainable.
4. When fixing bugs
Some bugs are typos while other bugs represent flaws in our designs. Often, a bug in code is the symptom of a flaw in our development process. At the very least a bug represents a missing test in the system that should have been there. It might be missing because it was difficult to write, in which case we can refactor the code to make the test easier to write and then write the test. Then, when we fix the bug, the test passes and all is right with the world again.
5. When adding new features
The cheapest, safest way to add features to a system that cannot already accommodate them is to first refactor the code so it can accommodate the new feature and then, after the code is refactored, add the new feature. We never want to get into a situation where we’re making multiple kinds of changes to code at the same time. Refactoring code to accommodate new features often involves adding abstractions and interfaces that make it easier to enhance a system with new features in the future. Once refactored it should be straightforward how to add the feature to the code.
6. When you need to document legacy code
Some code is really hard to understand and can be helped by some simple refactoring and clean up before documenting. The purpose of creating documentation is to increase supportability and this is also a major reason for refactoring.
7. When it’s cheaper than a rewrite
It’s almost never wise to abandon a legacy system in production for a total rewrite. Rewritten applications often end up with as much technical debt as the original. If you don’t do things fundamentally different when you do a rewrite you’ll likely end up with the same problems you had before. Refactoring is a safe, systemized way of cleaning up code a little bit at a time while the system remains in production.
Refactoring is expensive and there’s a lot of code that needs it. In order to make the best choices with our limited resources we have to be selective with what we refactor. Anytime we need to touch code, for example to fix bugs or add features, is usually a good opportunity to refactor. When we take these refactoring opportunities we keep code more maintainable and easier to work with.
Previous Post: « Seven Strategies for Helping You Justify Why to Refactor
Next Post: Seven Strategies for What to Refactor »