Refactor for Life
Eric N. Bush
There are certain fundamental laws of the universe that we just can’t escape. One of these is the Second Law of Thermodynamics as it applies to the general branches of science. It says that everything moves to a state of equilibrium and an increase in disorder, or entropy. This is even applicable in the field of computer science. Software systems tend to become increasingly disordered and complex as they are developed. When software reaches that critical point where it has aged and cannot be maintained, we bestow upon it the venerable title of Legacy Code. It might sound prestigious in another field, but when it comes to software, Legacy Code is a title no one is anxious to own.
The underlying reason for code becoming such a mess is that software development is an iterative process. Developers don’t start with a thorough blueprint that covers every detail to follow from start to finish. Instead, you start with a small kernel of code and expand it from there, adding to it from all sides until you have shaped the application into what you set out to create. But, if you’re like most developers, you don’t keep your code tidy as you rush towards shipping. This is made worse as project requirements and feature requests cause unforeseen changes in the code.
Development teams, of course, recognize this deficiency in their process and occasionally, when time permits, sneak in a little code cleanup work. This is typically done near the end of an implementation phase. But since developers want to be careful not to break anything that is already working, they don’t do the massive cleanup that is really needed. At this point it is all about managing risk and, as the saying goes, "if it ain’t broke, don’t fix it."
The more rigorous and official process of doing a cleanup is called refactoring. It has to be a way of life, something that is fully embraced and done right from the first day of implementation. This practice basically involves cleaning up your code as you write it, when you recognize ways to make it simpler or better structured without changing the functionality. Refactoring ranges from simple code cleanup to more complex design changes. It does not, however, involve fixing bugs. Strictly speaking, if you have a bug in your code and you refactor, the bug should remain because basic functionality (right or wrong) should not change. Before you start, you must first have a good set of tests to run. Without tests, you can’t be certain that the refactoring has not changed behavior.
If you have exhausted your own ideas on how to refactor your code, you can refer to Martin Fowler’s book Refactoring: Improving the Design of Existing Code. This has become the authoritative book on the topic. Fowler actually catalogs the different situations that require refactoring techniques and gives these names, such as Encapsulate Field, Extract Class, and Extract Method. For the Extract Method technique, you identify some code that can be taken out of an existing function and made a separate function. You might do this because the original function was too large or because you found out that the code was duplicated in more than one place. Visual Studio® 2005 contains a refactoring feature that makes it easy to perform several of the techniques. Here are some tips for successful refactoring:
- Have a comprehensive set of tests ready before you refactor.
- Make refactoring a regular part of your day-to-day coding practice.
- Make changes one at a time, continually verifying with tests that the code still works.
- Don’t jeopardize shipping; minimize the practice towards the end.
- If you inherit code that is poorly structured, consider refactoring the overall design first.
If you follow these practices, you will see many benefits. Having code that is less complex and better organized simplifies maintenance and makes future development more productive. Transfer of ownership is smoother. You usually end up with fewer lines of code. All of these benefits can translate into higher quality code. The crucial point is that you need to make refactoring a way of life. As messy code piles up, it gets harder and harder clean up. Don’t let yourself get to that point.
Perhaps we need to invoke the Third Law of Thermodynamics, which states that entropy in a system approaches a minimum value when the temperature is equal to absolute zero. Applied to the field of computer science, perhaps this law would state that software developers are kept from writing messy code when their office temperature is kept near absolute zero.
Eric N. Bush is a software development lead in the Engineering Excellence group at Microsoft. He works as an internal consultant and classroom instructor driving engineering and organizational improvements in the areas of people skills, process, and technology. Reach him at firstname.lastname@example.org.