Refactoring – Techniques and Tips
Most of the modern day software developers understand the significance of code refactoring and how it is crucial to keeping a system’s codebase healthy and maintainable. Put in simple terms, refactoring means modifying or reorganizing the structure of your code without altering the intended behavior of your system. There are different techniques of refactoring that are out in the wild. This blog post explores some of these techniques and how you can internalize them as part of your software development workflow. As seasoned practitioners of refactoring would point out, the most important pre-requisite for refactoring is a solid and reliable regression test suite for your codebase without which refactoring is an endeavor not worth undertaking. A green test suite post refactoring affirms that the changes that were made did not inadvertently alter your system’s behavior.
Lets start by briefly talking about the very popular RED-GREEN approach to code refactoring. This lays the foundation for all forms of refactoring. The idea behind this approach lies in the premise that refactoring goes hand in hand with developing the features of your system. You incorporate refactoring into the test driven development cycle by starting with a failing (RED) test, writing the simplest code possible to get the test to pass (GREEN) and finally work on improving and enhancing your code while keeping the test GREEN. This approach can applied to building a unit of the system or, on a broader level, to integration of several units of the system that make up the feature. The single biggest benefit of this approach is how one can seamlessly integrate refactoring into your overall development process and work towards keeping code clean. There are two distinct parts to this: writing code that adds a new function to your system, and improving the code that does this function. The important thing is to remember to not do both at the same time during the workflow. A lot of developers (including me) are found to be guilty of doing this sometimes. Please don’t.
Refactoring doesn’t have to be always part of the feature development workflow as stated earlier. As a developer, there are things you can do to your codebase to make the building of your next feature a little more painless. Martin Fowler calls this preparatory refactoring. This again can be executed using the RED-GREEN approach described above and sometimes without if the process is not ad hoc. Preparatory refactoring can also involve paying down technical debt that was accumulated during the earlier phases of feature development. Even though the business/end-users may not see eye to eye with the engineering team on such efforts, the developers almost always appreciate the value of a good refactoring exercise.
There are two types of refactoring efforts that I classify based on scope and complexity. One that is fairly simple and doesn’t need to be shoe-horned into the priorities of your development cycle. Examples of this type of refactoring include things that developers can execute with very little sweat such as method or class renamings, extract method, preserve object, etc. On the other hand, you have these giant refactoring exercises that can take several man-hours. These obviously have to be planned refactoring efforts since they can be complex and have wider impact on the system. Branching by abstraction is a technique that I have seen some of the teams use to take on large scale refactoring. The basic idea is to build an abstraction layer that wraps the part of the system that is to be refactored and the counterpart that is eventually going to replace it. The refactoring effort can progress in its own pace because of the existence of this transparent layer.
Refactoring often always helps but with one caveat – Making the right choices when it comes to executing large scale refactorings. It is extremely crucial to learn to find the right balance between building your system and refactoring the code that you write. Building a culture that encourages clean design and refactoring is easier said than done, but investing energy in that direction is never unwise.
Leave the campground cleaner than you found it