Monday, March 3, 2014

Learning to Refactor

I'm starting a new job tomorrow where I'll be maintaining an iOS application that was built by a string of contractors, with little continuity.  To prepare myself, I'm reading Michael Feathers' Working Effectively with Legacy Code and Martin Fowler's classic, Refactoring.

"Refactoring, oh I know what that is," I had said to myself.  "I refactor all the time, like back in high school when I rewrote my QBasic quiz game to read all the questions and answers from a file, instead of hard-coding them.  You know, back in 1998."  Hmm.

So maybe I didn't know much about refactoring at all.  It helps that there are definitions.  This is from Fowler:
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
But wait, there's more:

Refactor (verb): to improve software by applying a series of refactorings without changing its observable behavior.

Did you notice the redundancy?  I underlined it so you wouldn't have to squint.  I appreciate DRY, but I won't pretend that I know more than Fowler.  Clearly, he's gone out of his way to repeat something because it's important: Refactoring should not change observable behavior.

Ok, great.  So my QBasic Jeopardy refactoring was exactly that.  I moved the questions and answers out of my code and into a file, but the behavior of the game didn't change.  Well, maybe it was refactoring.  But it wasn't careful or methodical.  I'm sure that, halfway through, I thought of another feature and coded it in immediately.  I had one unit test, and it was built into my keyboard: F5.

Of course, I don't have any regrets about this.  I don't look into the mirror and berate my 16-year-old self and wrinkle my nose at his disgusting, smelly code.  Really I don't.  But wouldn't now be a great time to learn to refactor?  Wouldn't right now be a good time to start writing unit tests meant to enforce every tiny expectation about the behavior of my code? 

(The answer's yes.  Also, I underlined it for you.)

My project this past weekend was to add unit tests to my own iOS application, WhichBill.  In my next post, I'll let you know how it went.