Refactoring is improving the internal structure of code without changing its external behavior. Refactoring gives developers another chance to improve their designs and often gives management a cheaper and less risky way to ready an existing system for adding new features. Here are seven strategies to help you justify why to refactor code.
1. To learn an existing system
Refactoring code is a great way to learn the code and to embed what’s learned into the code. For example, replacing or wrapping a poorly named method with a better named method gives us the opportunity to improve the readability of code. At the same time, we’re learning how a system works and embedding that knowledge into the source code, in this case through providing a better name.
2. To make small improvements
Safe refactorings are the subset of refactorings that are relatively straightforward to perform. Many are automated by development tools to do things like easily rename, extract, and move methods and classes within a project. I find I constantly use these refactorings as I’m writing code so that it continues to reflect my evolving understanding of the parts I’m building.
3. To retrofit tests in legacy code
All refactoring reduces the cost of three things: adding tests, accommodating new features, and more refactoring. As we refactor code we see opportunities to improve the design and add more unit tests. As we add better tests, we gain more confidence to perform more involved refactorings, which reveals even more opportunities to write better tests, and so on.
4. Clean up as you go
Refactoring should be something we do all the time. Coding is often a process of discovering what works. We may not know the right approach as we’re figuring things out so as we learn more we get the opportunity to improve our code, update names, etc. and this is vital for keeping our code clean. If you do TDD then you know one of the key steps in the TDD process is to refactor code once you get an implementation working. We do this to improve supportability, reduce the cost of maintenance, and increase extensibility.
5. To redesign an implementation now that you know more
Even with continuous refactoring it’s still possible to accumulate technical debt during development. When you get new information that changes your existing design or you need to implement a new feature that your current design can’t handle then it may be time to refactor in the large. This can include a major redesign and re-implementation of code to make it simpler to add new features later.
6. Clean up before moving on
Once you get something working, before moving on to the next task refactor the existing code to make it more supportable. Now that you know what each method is really doing, ensure they’re named well and clearly express their intent. Make sure the code is easy to read and well laid out. Break out small methods from larger ones and extract classes when necessary.
7. Refactor to learn what not to do
The majority of software in production today has accumulated much technical debt and is in bad need of refactoring. This may seem like a daunting task, and it can be, but refactoring code can actually be pretty fun. I find I learn a lot when I refactor code and after a long session of cleaning up other people’s mistakes (or my own) I tend not to commit the same acts of irresponsibility when I write new code. The more I refactor the better developer I become.
Refactoring is all about reducing risk and waste. High performing development teams can appear to spend up to half their time refactoring code, but they’re also improving their designs and building in supportability, which can quickly repay the effort. Since code is read ten times more often than it’s written, refactoring to clean code can pay for itself very quickly.
Previous Post: « Seven Strategies for Effective Retrospectives
Next Post: Seven Strategies for When to Refactor »