During a pairing session today, we spotted some duplicated code and a period of refactoring ensued. The code in question related to some simple DB queries – the code for getting a connection, returning results and cleaning up was duplicated, with only the query and the exact part of the result set required being duplicated. We already had some code which could be used to remove this duplication – previously someone had written a DB visitor which was being used internally in a test class.
Extracting the visitor code out into a class in its own right was trivial. What was not was replacing the repeated code. After 10 minutes of head-scratching we had to ask ourselves the question “is this still refactoring”?
Let’s look at what we had done – we’d extracted out our visitor code to make it an object. The existing code using the visitor still worked. We couldn’t get other code using our visitor happily quickly. We decided to leave it and move on – the rational being that refactoring should be something quick you do in the normal test-code-refactor process. If you can achieve a quick win that improves code outside the scope of what you are working on, then great – but when improving code outside the purview of your current task takes too long, it feels like going off at a tangent.
Here the decision to stop came because the refactoring was taking too long – however it was in my mind still refactoring – and work that should be done at a later date. Frequently however I see people overuse the term refactoring to cover what I would think of as being redesign/re-architect. Refactoring as I see it involves small, incremental changes to the code you are working on which shouldn’t take more than five or ten minutes. What I am unsure of is how to treat those tasks that sit somewhere in between. A 5 minute change is a refactoring. A change that takes a day isn’t. What about a change that takes an hour? Or two hours?
Why should we care what is and isn’t refactoring then? Well, refactoring is an acceptable task to carry out whilst fulfilling some specific task (be it bug fixing or adding new functionality) . When you go beyond the bounds of a simple refactoring you run the risk of going off at a tangent, of loosing focus of the job at hand, without necessarily adding anything the business actually wants. Perhaps that is the answer – when you feel yourself getting too far away from the current task you know you’ve stopped refactoring and started doing something bigger.