Pattern Name: Refactoring In Very Small Steps
Problem
How do you avoid to get lost by doing several things at the same time during refactoring?
Context
You are developing software and you want to make some refactorings before continuing coding. You followed TheFirstRefactoringStep. You are now ready to refactor your code.
Forces
Refactor in very small steps. A common routine to follow can be: find the smallest useful change you can make. Make it. Then TestEveryRefactoring.
Resulting Context
Introduced errors during refactoring will be easy to find because the changes will be so small. You won't have to spend a lot of time debugging to find bugs. After refactoring, you should apply TestEveryRefactoring. If the volume of changes involved in the refactoring is big enough, use the BacktrackIfRefactoringFails to keep your code safe.
Rationale
Refactorings change the code of a system. As these changes are bigger, people run the risk of making mistakes that may break the system functionality. Besides, carrying out several operations at the same time may confuse developers, causing that they need to throw all their changes away.
Therefore, you should apply refactorings step by step. After each small refactoring, you must to compile and test the system to validate its integrity. As Martin Fowler wrote in his book [1], followed this approach, "(...) if you made a mistake, it is easy to find the bug". You'll never get lost because you have complete control over applied changes because they are very small.
Origins
This pattern come from the WIKI pages about refactoring [2]. The original reduced pattern was: "You want to refactor code, and you don't want to introduce errors while you're doing it. You also don't want to get lost by doing several things at the same time. Therefore, refactor in very small steps. Find the smallest useful change you can make. Make it. Then Test Every Refactoring".
Acknowledgments
References
[1] Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts. Refactoring: Improving the Design of Existing Code. Addison - Wesley, 1999.
[2] Wiki Pages About Refactoring. Available at: http://c2.com/cgi/wiki?WikiPagesAboutRefactoring. Last confirmed: June 26, 2004.
Author: SantiagoValdarrama
Therefore, refactor in very small steps. Find the smallest useful change you can make. Make it. Then TestEveryRefactoring.
This should save you a lot of debugging time.
Example. Let's say you have this complex method that uses a lot of temporary variables. Using MethodObject, you first create the new object. You compile. You change the original method to use the new object. You compile and test. The new object now has a single complex method called compute(). Using ExtractMethod, you define a new method that does part of compute()'s work. You compile. Now you change compute() to use the new method. You compile and test. And so on.
If you do a major refactoring, you may have large portions of the code checked out for extended periods of time and cannot check it back in until it is all done. Instead, refactor in very small steps. Create intermediate steps that were not part of the original code and will eventually be removed, but allow you to check code back in as quickly as possible. Create shims and parallel interfaces so that all of the code does not have to migrate at once; these can be removed when they are no longer needed.
ReFactor in small steps and you can stop the refactoring at any point in time. When the boss comes down the hallway with a brand new, must have feature, you can say give me 5 minutes and I'm ready instead of hoping you can finish a large refactoring by the end of the week without breaking things too badly.
When refactoring ugly code, I frequently come to a place where I see I cannot continue with my current small refactor without first refactoring something else (which may or may not be small). Since I have a number of changes checked out of SCM, (and this is a suggestion for the "Forces" section), I find I'm rather annoyed and don't want to backtrack--the effort to do so is sometimes not trivial. So this force could be named, "frustration of backtracking." I still advocate for backing out your current refactoring, refactoring the dependency, committing, reapplying the original refactoring and continuing. Is that a separate pattern? --JasonFelice
This page mirrored in WikiPagesAboutRefactoring as of April 29, 2006