Applying UML and Patterns has a short 9 page introduction to Refactoring. I develop my applications using Test Driven Development from eXtreme Programming (XP), so refactoring is not new to me. However, since I have yet to read a book on Refactoring (it's on my list), my skills in refactoring are probably a bit more practical and rough around the edges :)
I like the definition of refactoring as presented in Applying UML and Patterns, which originally came from Fowler-
“Refactoring [Fowler99] is a structured, disciplined method to rewrite or restructure existing code without changing its external behavior, applying small transformation steps combined with re-executing tests each step.”
The activities and goals of refactoring are:
- Remove duplicate code
- Improve clarity
- Make long methods shorter
- remove the use of hard-coded literal constants
- ...
These goals are based on Code Smells, which are hints that something may be wrong in the code:
- Duplicated code
- Big method
- Class with many instance variables
- Class with lots of code
- Strikingly similar subclasses
- Little or no use of interfaces in the design
- High coupling between many objects
- ...
Refactorings have names, just like Design Patterns, to help communicate the refactoring methods-
- Extract Method - Transform a long method into a shorter one by factoring out a portion into a private helper method.
- Extract Constant - Replace a literal constant with a constant variable.
- ...
All in all, the 9 page chapter was a decent introduction for beginners to the concept of refactoring.
From my own experience, I have a few thoughts about refactoring.
First, a cool Visual Studio.NET Add-In that helps with c# refactoring is JetBrains Resharper. It does a lot more than just refactoring and is a must buy until Visual Studio 2005 comes out. I am unaware of a VB.NET refactoring tool, but I am sure a Google search will find you one.
Second, a lot of refactoring is created by the process of Test-Driven Development, which is basically a methodology to create a test, watch it fail, and then do the simplest thing possible to make the test succeed. Due to “doing the simplest thing possible to make the test succeed,” you end up applying a lot of refactoring patterns during the development process to get the code up-to-snuff for the real world.
Third, refactoring feels a lot like database normalization to me. There are several levels of database normalization and realistically you probably won't apply all of them based on time constraints and application needs. The same goes for me with refactoring. At some point you may end up doing refactoring for the purposes of refactoring and not for any real business / application need. You have to decide what code smells you can live with for your application.
Fourth, the whole refactoring process seems very “un-agile” to me based on its very definition, which is essentially “changing code without changing its behavior.” :) Why the hell would you want to change code that has no effect on the final outcome ? :) I am saying this tongue-in-cheek, but it is an interesting comment and as I mentioned in my third point, you could end up refactoring to the point where you don't have spaghetti code but ravioli code.
Visual Studio 2005 will have refactoring for C#, but unfortunately, VB.NET will not have much (if any) refactoring. A couple of books that I will probably eventually read on refactoring are:
- Refactoring: Improving the Design of Existing Code by Martin Fowler - Amazon
- Refactoring to Patterns by Joshua Kerievsky - Amazon