Usul’s Words Have Power, Part 1: Refactor

work safe

Words have power. For those who practice the Weirding Way (from Dune), this is to be taken for granted. Some agree with the Humpty Dumpty (Through the Looking Class Ch. 6) and a word means exactly what they choose it to mean. But, to counter that point, I offer the following description of my dinner last night; “Proxy Flu quickly house Cabbage’s”. Communication is based on a shared understanding, so let’s share. More correctly, I’m going to share with you what I mean. Then we’ll communicate.

People are still confusing Refactor with Redesign.

As we bound through the local community and the wider internet, it is all too common we hear something like, “We have no time to Refactor, It’s a nice to have, but we can’t”. I have also heard, “We give our team one month a year to refactor and do stuff for us.” I humbly submit, “You’re doing it wrong!” I understand that’s an inflammatory statement. I intend to back up those words, so bear with me through a metaphor.

I’m baking a cake. I was making a five course meal for the in-laws when they suggest that a cake would be nice. I really want to get that cake out and onto their plates, and I want to impress them. I look around the kitchen and realize that I’ve just used my last big bowl making the batter. I need to frost the cake, but I need the big bowl to make the icing. I reach for the nearest bowls I can find, four small bowls of different sizes. Now I have to make several small batches of icing to get the same amount. I have risks. My calculations of the ingredient proportions could be wrong. I can underestimate the size of the bowls. I can combine the ingredients in an inconsistent manner. Worse, it take four times as long to make the icing, because the time it takes to make icing isn’t directly related to the amount you make.

That was one option. Another option is to stop everything and clean all the dishes at once. But I would very literally be starving my in-laws. The last plan is to clean the big bowl and maybe a beater and spatula I could use, but only those that I need. Then, when I’ve finished, I could clean up the dishes I used for the cake. That is Refactoring.

What is implied by the statement, “we don’t have time,” is that they want to stop and clean everything. That is a redesign.

In pondering why the misunderstanding exists, I can only blame myself and other proponents (not really, but I’m making a point about misunderstandings). When talking about Refactoring, we usually start with a complete program and make changes. We don’t have a choice because we want to isolate the Refactoring act for pedagogical reasons. But it tells only half the story. A half that gives the impression this is a post-development effort. In addition, when talking about the power of small steps adding up we mention it’s possible to redesign from a series of Refactorings. But the point to drive home in that situation is lost. The code never stops being developed. We do this to express the notion that if you clean the dishes as you go, you’ll never have to wash all the dishes in the house.

When do we Refactor? At one extreme, the TDD side, you Refactor after every passing test. On the other extreme I should get my feature working, check in, Refactor and check-in again. I don’t wait until the end of the quarter. That is a Redesign, not Refactoring.

Let’s lay down one more time why we Refactor. Our first pass at solving a problem is littered and strewn with a confused jumble of ideas. Refactoring gives us a chance to solidify our abstractions, improve readability, increase reuse, manage dependencies, increase testability, and clarify APIs.

How do you start in an existing project? Clean the code you’re currently using. Not to make it perfect, but to reduce the risks of spaghetti code. If you start with a pile of dirty dishes and clean only what you need, you won’t clean all the dishes, but you will clean the ones you use most often, and they will always be clean when you need them. You didn’t mean to write bad code, you just forgot to wash the dishes.

4 Comments

4 Comments

  1. Rachel  •  Sep 28, 2009 @7:44 am

    Hi Brian,

    I am interested to know whether you suggest using 3rd party tools to refactor, or indeed if you personally use any 3rd party tools to get the job done?

    Great post, I particularly like the cake analogy,
    Rachel.

  2. Ball  •  Sep 28, 2009 @8:45 am

    Rachel,
    In the last few years, I’ve been bouncing from project to project, mostly to different environments. Some have excellent refactoring support and some have almost none. I feel that you don’t need it. But it helps. To offer an analogy, I can build a bookcase with a handsaw, but a few power tools make it both practical and easier to get right.

    My friends can’t say enough about Resharper from JetBrains (they got in the door by giving IndyALT.NET some licenses.)

    I started exploring Devexpress’s CodeRush Xpress after hearing Hanselman talk about it. I’m not using it day-to-day because I’m currently on a regulated project and we’d have to verify it. I like what I see so far (and this is Rachel’s product judging by her email address).

    The refactoring support for Java in Eclipse is great.

    TestComplete’s JScript environment has no refactoring support, but its recorded test steps make it critical. The generated code is legacy by default.

    Ruby and VIM don’t have any out of the box refactoring support.

    I’m a fan of tools but, as my woodworking career can attest, tool envy can block you from doing anything but yearn for a real table saw. On the other hand, a good tool can lower the barrier to good practice and make it more likely you’ll do the right thing.

  3. Michael Brown  •  Oct 3, 2009 @1:32 pm

    Brian, great job at identifying the difference between redesign and refactoring. A term I like to use is what I call “opportunistic refactoring” (or drive-by refactoring) that is, if you’re doing a feature that uses existing code, be on the look out for opportunities to refactore the existin code (rather than trying to shoe-horn the new feature into code that was created without that feature in mind).

    Also, you might want to look at JetBrain’s RubyMine for Ruby refactoring support.

  4. Bruce  •  May 19, 2010 @10:39 am

    Brian, great job at identifying the difference between redesign and refactoring. A term I like to use is what I call “opportunistic refactoring” (or drive-by refactoring) that is, if you’re doing a feature that uses existing code, be on the look out for opportunities to refactore the existin code (rather than trying to shoe-horn the new feature into code that was created without that feature in mind).

    Also, you might want to look at JetBrain’s RubyMine for Ruby refactoring support.

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>