Reading Refactoring – Part 1

11 Jan

or Fowler vs. Red/Green/Refactor

In an effort to overcome my self-taught programmer deficiencies, I’ve been reading more programming books recently.  I recently finished The RSpec Book, and experienced something of a revelation about Behavior Driven Development.  Basically, the revelation was that in the process of writing objects that are easier to test, you end up writing objects that are less brittle and more reusable.  It’s one of those things that I’d heard before, but had never really clicked until I got the chance to see an example of the process in depth.

Craving more examples, I turned to Martin Fowler’s Refactoring.  It’s a book that consistently makes its way into top 10 “most influential programming books” lists, and that I’d been meaning to get around to for a while.  I haven’t finished it yet, so this post is less for other people’s benefit than my own.  I want to put some thoughts into words so that they become a little more concrete, but these thoughts don’t have much conviction behind them.

I was really struck by this passage:

Here’s a guideline…:  The first time you do something, you just do it.  The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway.  The third time you something similar, you refactor.

The above passage flows into a series of sections on when you should refactor: “Refactor When You Add Function”, “Refactor When You Need to Fix a Big”, and “Refactor As You Do a Code Review”.  It doesn’t get its own section, but Fowler also talks about refactoring as a way to better understand code you haven’t seen before.

If I was going to sum up the Fowler philosophy on when to refactor, it comes down to doing it only when you need to do something new with the code.  Even the “refactoring as a way to better understand code” thing is with the knowledge that you are about to be altering said code.  Without refactoring, the poor design decisions you made before will slow you down as you try to take your code further.  Refactoring is a way to undo those poor design decisions.  But for Fowler, there’s no need to improve the design if it isn’t actually holding you back.  Fowler says that, in the real world, he wouldn’t even have bothered doing any of the extended example of refactoring that makes up the first chapter.  He wouldn’t have considered it worth it.

All of that seems substantively different to me than the TDD/BDD mantra of Red/Green/Refactor (RGR).  RGR seems (and please forgive me if I am misrepresenting it) like a philosophy of constant refactoring, a philosophy that (if you followed it perfectly) would lead to nothing but beautiful code.  Fowler’s philosophy would lead to a more limited code beautification strategy.  Code as beautiful as it needs to be to move forward, but no more.

Of course, in a project of any complexity, code does need to have a substantial amount of craft and care in it in order for modifications to be made in a timely fashion.  Code produced by Fowler would almost certainly end up being pretty.  The two philosophies are definitely close to each other on the beautiful code spectrum.  What I can’t decide is if the RGR model is a natural outgrowth of Fowler’s refactoring or not.

Fowler’s book is old, after all (1999).  He is working in Java, and makes frequent mention of recompiling.  He talks about making sure that your tests are self verifying, implying that he isn’t yet working with a testing framework.  If he had a modern testing framework, and faster machines where recompiling took less time (or a language without a compile step, at all), in other words, if he had tools that made testing/refactoring cheaper, would he approve of the Red/Green/Refactor paradigm?

Perhaps.

There is also a question of vocabulary.  Is the Refactor step in Red/Green/Refactor is really the sort of refactoring Fowler is talking about?  Fowler is normally talking about code on the design level, and one point, he specifically states that he isn’t just talking about keeping your code clean.  But sometimes it seems that the Refactor step is largely about keeping your code clean.  Fowler has a list of refactorings, and “Rename Variable” isn’t one of them.  Personally, I think the Refactor step in RGR is a great time to make sure your variables have good names.

This book has been food for a lot of thought, but one thought that I think I will have to work through is how much refactoring is too much.  There is something very appealing about refactoring only when the old code is getting in your way.  You will still be refactoring a lot that way.  But by only doing the refactorings that  are necessary for functionality, or to maintain basic DRYness (as opposed to religious DRYness), you do seem to be better following the “you aren’t going to need it” mantra.

But then again, beautiful code is beautiful.  And it does lead to exceedingly clear thought, which is nothing to scoff at.

I feel this is the sort of question that can only be answered by experience.  If I want the answer, really, I better get coding.

Also, I better finish the damn book.

Leave a comment