Exploratory Refactoring consists in a series of small changes to source code which are made by the programmer in order to better reflect his/her comprehension of explored code.
As exploration is a way to discover places by walking throughout them and by drawing a map, likewise Exploratory Refactoring is a way to discover what a piece of code does by reading it and by rewriting little part of it.
Exploratory Refactoring is a technique a developer, who works on a legacy codebase, might use to understand the codebase logic before actually starting with the actual refactoring.
Understanding Legacy Code
Exploratory Refactoring is mainly a learning process. Once a developer has comprehended what few lines of code are doing, a mental model of such lines has been abstracted in programmer’s mind: the developer has the knowledge of that code. This knowledge might be then handed down to source code and consolidated in a refactored codebase, but not necessarily.
Michael Feathers, in his book Working Effectively with Legacy Code, considers these small refactorings just to understand what the code does. Once the developer has grasped such knowledge the refactored code can be thrown away. After this the actual refactoring can begin.
In the Feathers’s throw-away-refactoring approach a programmer can proceed in a Exploratory Refactoring session without being very careful both in applying the changes and in avoiding commit into the source code management system, because only actual refactoring deserves to be definitively committed.
Martin Fowler advocates small behavior-preserving transformations too:
Refactoring is a disciplined technique for restructuring an existing body of
code, altering its internal structure without changing its external behavior.
Its heart is a series of small behavior preserving transformations.
Each transformation (called a "refactoring") does little, but a sequence of
transformations can produce a significant restructuring. Since each
refactoring is small, it's less likely to go wrong. The system is kept
fully working after each small refactoring, reducing the chances that a
system can get seriously broken during the restructuring.
Martin Fowler has published an online Catalog of Refactorings. Some refactorings are so little, like Decompose Conditional, Encapsulate Downcast, Extract/Inline/Rename Method, Extract Variable, Inline Temp (alias Inline Variable), etc… , I decided to use them as part of my Exploratory Refactoring sessions.
Just as an example in the Extract Method refactoring a code fragment can be grouped into a method whose name explains the purpose of the fragment. So the following fragment:
1 2 3 4 5 6 7
can be refactored as:
1 2 3 4 5 6 7 8 9
Benefits of Exploratory Refactoring
I think Exploratory Refactoring has both technical and psychological benefits.
The main technical benefits is about increasing the developer understanding of the legacy codebase. Secondarily it improves the readability of the source code. If the whole development team performed Exploratory Refactoring when studying a new area of a large legacy codebase it could be noticed an ease in working with it as time goes by. Moreover the code studied during an Exploratory Refactoring session gives to the programmer an idea about how much clean, understandable and complex the whole legacy codebase is.
From a psychological point of view working on legacy software is exceedingly frustrating and demotivating, code is such an awkward one that the only valid measurement of code quality is WTFs per minute :-)
When frustration and demotivation dry out our attention studying legacy code could become an unproductive and effortful task.
In my opinion Exploratory Refactoring tackle quit well demotivation because it alternates the passive activity of reading with the active one of writing. Moreover every little refactoring we do makes code more beautiful to our eyes, so if we were able to enjoy of these little gratifications we would want more and more. Finally our refactored code increases our feeling of ownership over it, and this responsibility encourage us to continue working on it.
Exploratory Refactoring IDE Support
You won’t find anything like an Exploratory Refactoring menu in your favorite IDE, but the good news is your IDE certainly yet provides several refactoring features, probably more than you could imagine. Learn how to use them effectively!
Manual changes are more likely to introduce errors. Clearly if you are working with a statically compiled language, such as Java, the compiler can warn you when compilation errors are introduced; but if you are using a dynamic language, such as Ruby or Phyton, there is no compiler to rely on. So applying changes to codebase by the refactoring features of your IDE is safer compared to manual refactoring.
Share Your Opinion
Although I agree with Feathers on the fact that Exploratory Refactoring is mainly a learning process, I have mixed feelings about the throw-away-refactoring approach to it. In fact I like the way Exploratory Refactoring makes knowledge emerging and becoming more apparent, but I don’t understand why I can’t commit such improvement.
If you had any idea about why exploratory-refactored code shouldn’t be committed, please let me know, I’ll publish your idea as a comment to this post (I will not share your e-mail address with anyone else).