One common experience many companies have in the course of supporting software products is that the time and effort required to make customizations vary as the product ages. At first, customizations are easy because new features either mesh nicely with the existing code structure or they are completely new and can be easily added to the existing code. But as the product ages, changes affect other parts of the system, slowing down development and causing problems in seemingly unrelated parts of the product. The good news is that this isn’t an inevitable result of creating software. You can get around many of these problems by regularly refactoring code.
What is refactoring code?
Refactoring code is the act of changing existing code to be more understandable. Though it is possible to add functionality or fix bugs while refactoring, the act of refactoring code is a separate process from these activities.
Why in tarnation would you want to do that?
Think of writing code like writing a book. At first, a writer just needs to get his or her thoughts down. The book would probably be understandable after this first pass, but the reader would have to take more time to sort through the writer’s ideas. To help combat this, the writer will re-read, and in many cases, rewrite portions of the book. The idea is not to change the content of the book, but to make it more understandable to others. An editor will then read and change the book to further clarify the ideas it contains.
Many software products are shipped with code in the pre-edited state, in large part because the product’s users aren’t affected (at least not immediately) by the quality of the underlying code. This is usually a mistake, though, for the following reasons:
- In most cases, other developers need to read the code to make fixes and improvements. This is significantly easier (therefore cheaper and faster) to accomplish if the code has been refactored/edited.
- Debugging code is harder to do than writing code in the first place. Anything a developer can do to make the code easier to read in the future will save effort in the long run.
In short, code that has been refactored is easier to understand, therefore easier to extend and debug when enhancements are needed in the future.
But the business stakeholder wants their change put in now
There are times when it is appropriate to hold off on refactoring in order to put more features in. These times should be rare and temporary. In most cases, if you explain to each stakeholder what you are trying to do and why, focusing on why the delay benefits them (which again is that you’re building a foundation to help make the system more easily maintainable in the future, lowering time and cost in the long run), you’ll get agreement.
There have been times in my career when this hasn’t been enough to persuade the stakeholder; it was always in situations where the development team had consistently over-promised and under-delivered on software quality. In these cases, the development team needs to rebuild trust, and one way to do this is to communicate how refactoring will improve the reliability of the process and the quality of the product.
Many developers want to refactor everything. Should you let them?
Some developers, especially the better ones, tend to want to refactor everything. This isn’t always the appropriate course of action. If you remember the purpose of refactoring, which is to make code easier to maintain in the long run, it shouldn’t be hard to see why. Some code simply will never be touched again in its lifetime. Why spend the time polishing code that isn’t broken and will never be changed? With that said, though, I usually recommend refactoring code sooner rather than later, while the purpose of the code is still fresh in the developers’ minds.
How can you help prevent refactoring from breaking the software?
After the cost, the second most common concern I’ve encountered about refactoring code is the risk of introducing breaking changes to the software. No, end users generally are not understanding when something that worked is suddenly broken. Why risk making a change? Fortunately, automated unit testing is a fantastic way of mitigating this risk, but a further exploration of that concept will have to wait for my next post.
This article is published as part of the IDG Contributor Network. Want to Join?