No, Wait! Do it in an Object to Begin With!
Just this weekend, I went through the inspector / workspace / object cycle with a partner. We had damaged the database and needed to remove the damaged objects. We inspected until we understood what was going on. Then we put the code into a workspace, and ran it until we were sure it was finding all the bad objects. Then we quit for the day – it was already quite late. The next day we built an object (DatabaseFixer), moved our workspace method into it, and began refactoring. We tested frequently along the way. At the end, the method was refactored into about 8 or 10 methods, and we were much more certain that the Fixer was working correctly. Then we ran it without incident. The resulting Fixer class is quite likely to be useful in similar circumstances, and we can see how to enhance it if the situation isn’t quite the same.
All in all, it took a couple of hours to develop the thing in a workspace, and a couple of hours to refactor it. Not bad at all.
In retrospect, however, it would have been much faster if we had started with the DatabaseFixer object. When we refactored, we looked at our huge method, and removed chunks that might make a separate method. The original method was a huge loop that processed: all people; selected people; their bins; their parts; their bins with bad parts.
The final object actually looks like that is what it’s doing:
self peopleToProcess do: [ :each | self processPerson: each]
and so on. Each individual method just does one loop, and states clearly exactly what it is about. There was one odd blob of code that built a dictionary of dictionaries of dictionaries of collections, and it’s still in there, all in one method. Because it isn’t in the middle of a loop and processing eachThis and eachThat, even that method reads more clearly than the original.
If we had just begun that way, we could have expressed our intention as we went along. Instead of concentrating on our weird dictionary structure (even if we had wound up with it), we would have been concentrating on the overall operation of the fixer. Methods would practically have written themselves, I’m sure of it.