Effective Refactoring Strategies
Out Of Date Warning
Languages change. Perspectives are different. Ideas move on. This article was published on December 21, 2012 which is more than two years ago. It may be out of date. You should verify that technical information in this article is still current before relying upon it for your own purposes.
Including today, there are six business days remaining in 2013 (five if you are lucky enough to get New Year’s Eve off). My brother used to call this week “the lost week” – there’s hardly anything to get done because so many people are on vacation or preoccupied with setting goals for the new year. But the downtime provides a perfect opportunity for the aspiring software developer to do the one thing they are always told there’s no time to do: make the code better for better’s sake.
With few deadlines and plenty of free time, most developers can get a few hours of refactoring in to their code towards the end of the year. They can rearchitect sections that were implemented with haste in September; they can write tests for sections that were untested in April. Put another way, the “lost week” can be redeemed.
But before you dive into your code base in earnest, there are some considerations you should take.
Test Everything First
This is the easiest way to avoid a phone call Christmas morning from a frantic boss who tells you that the whole system collapsed overnight. Without writing unit tests, you won’t have an effective strategy for ensuring the code continues to work, even as it’s structure changes.
I am by no means an expert on writing unit tests. But Chris Hartjes is: he wrote a book on the subject and blogs regularly about it. The bottom line is this: tests help ensure that you are in a position to have confidence that your changes did not break your application in some unexpected way.
Without tests, moving code around could fundamentally break your application and you would never know, because unless you manually test every part of an application for each release, it’s likely you’ll miss the bug. And as an application grows in size, it becomes more and more impossible to follow all the code paths to identify bugs manually. Unit tests help identify them in advance. Refactoring is a mistake unless you’ve got tests to back it up.
One Method, One Job (Also One Class, One Job)
Make sure that your code applies the single responsibility principle, not only in class abstraction but in method abstraction. Methods that have more than one job are inherently less reusable than methods that only have a single role. Beyond that, it is more difficult to identify failures when a method or a function has more than one role.
Common areas for improvement involve methods that contain string manipulation code, or code that validates data. These are prime candidates for refactoring. Mathematical operations are also prime candidates for a refactoring operation.
Just as there’s a danger in abstracting object oriented applications into lasagna code (I write more about this in my book), it’s also possible to overdo the refactoring of methods and functions. A good rule of thumb is that removing code for a function should make the code more reusable and easier to test; if it doesn’t pass these two tests it may not need to be removed.
Don’t Be Afraid Of More Objects And Classes
The single responsibility principle means that you will inevitably end up with more objects and classes. This is fine! In fact, this is preferable to having one large class that contains many behaviors.
Objects are not inherently bad. They don’t destroy your computer or make your application slower in the number used by most developers. If you have a reason for an object to exist, by all means create it.
Remove Dead, Unused, Unnecessary or Old Code
Most code bases have code laying around that is unused, unneeded, or old. This code can be removed and should be removed periodically. This is a good time to take advantage and remove this code.
Read the code carefully and run the dead code detector over it to see what parts are no longer being used. A prime candidate for removal are variables that are no longer used, but are still defined. Don’t micro optimize the code, but give it a critical eye toward improving it and cleaning it up.
It is also possible here to tighten business logic and improve the flow of the code, but proceed with caution and make sure you have tests!
Document Your Code
Nobody has enough time to write the documentation they want, inline or otherwise. Take the downtime as an opportunity to go back, write docblocks, and otherwise document the code that you wrote over the past year. Though this is often a tedious process, it has its benefits, especially when you come across a function you wrote this time next year, and have no idea what it does (documentation solves this problem).
Consider using a standardized format for your document blocks. Not only does it make compiling them into readable documentation easier later, by having a standard format that everyone follows it makes it possible to use the documents in your IDE or other coding tools.
There are currently no comments.