Monday, May 4, 2009

Why we refactor code

Formulating an explanation in plain English for the non-technical

Late last week I received some “intelligence” that during a product meeting, one of our senior stakeholders exclaimed something along the lines of

“Why haven’t we made more progress on new features? Why have we spent all this time on refactoring? I don’t care about refactoring, it’s just fluff and no use to me.”

Unfortunately I missed this meeting. Or maybe it was fortunate. I don’t know that I’ve ever had to articulate to a non-technical person the purpose and benefits of refactoring code, and may not have done a great job if I’d tried to ad-lib. So over the weekend I mulled it over a bit, looking for a way to explain it that would resonate with someone like this.

The explanation had to be quick to explain and make patently clear the need for, and benefits of, refactoring. That itself got me thinking more deeply than ever before about why we refactor. Below is what I came up with. It’s all expressed in the context of the particular product that gave rise to this challenge, but I think the argument holds up across the board.

Here’s my basic premise: building software is like a game of Jenga™, and if you don’t do an appropriate amount of refactoring over its life the game will end sooner rather than later and everything will come crashing down. If that sounds odd, bear with me and I’ll explain. Let’s start with some background on the product that had given rise to the question:

  • The product is a framework from which we build dozens of in-house web applications. They are all basically CRUD applications which vary a little from the functionality of the main framework (additional fields for example).
  • The framework has had 7 releases over 5 years
  • The first release had just over 1100 classes, the latest release has nearly 1800. That’s a 60% increase.
  • Over its lifetime, at least 18 different developers in three different offices in two different countries have worked on it. There’s never been more than five people working on it concurrently so that’s a fair amount of staffing changes.
  • The applications we build from this framework have the expectation that they can upgrade (or migrate as we call it) to newer releases of the framework than that which they were built upon

Now let’s build (no pun intended) the Jenga analogy. Consider each block in the stack is some piece of code, a class perhaps. Now obviously classes are more complex than this – they vary in size and have more complex dependencies, but as a simple model this will work.

Now, each release of the framework involves coding. That often means changing an existing class: pull out a block, "tweak" it, and then of course stack it on top. This represents how modifying existing code can lead to a more fragile situation. Unlike regular Jenga where you just use the existing blocks in the tower, coding involves adding new blocks. So your tower gets bigger over time, potentially making it a little more wobbly too. The other notable difference to help complete the analogy would be that whereas Jenga is played with 54 blocks, my framework here started with over 1100. And of course aggressive deadlines mean one doesn’t always have enough time to carefully consider how to position those blocks to best effect, but that’s how it goes...

After a few releases, our tower is looking pretty wobbly, although it still “works” just fine to the casual observer. After all, it’s still standing.

Business users: “We need you to add this new stuff.”

Engineers: “But those blocks are a completely different shape. Some of them are really oversized, and heavy. Besides, have you seen the foundations?”

Business users: “Yeah but if you could just tack them on somehow, that’d be great.”

See the problem is that the blocks are all rather precarious now. And some of them we never wrote ourselves we just use them. But they’re old, unsupported and clunky. We need to replace them or update them. We need to shore up the foundations. We’ve also noticed in the last five years that the business uses them in ways we didn’t appreciate when we first assembled them.

We need to reorganize the blocks a bit. We need to get rid of some of them, we need to simplify them. We need to shore up the foundations. We need to make some new blocks too, better suited to the way we have learned they actually get used. Considering how much we use them that’ll save money. In short, we need to refactor.


  1. "You know that moped you got us 2 years ago? We need you to attach this trailer to your moped"

    "Hmmm...what? It doesn't have anything to attach it with, and besides, it can't pull it. It's a moped!"

    "Well, we have business reasons to attach a trailer to a moped. Chop chop! Oh, and you have two days to figure it out"

    "Hmm...ok, I can cobble something together, but I warn you, it won't go very far."

    6 months later:

    "So, how can we increase the size of the trailer and the range the moped will go?"

    "What? I warned you 6 months ago that it wouldn't go far!"

    "Well, we have business reasons to double the weight of the trailer and triple the length of the trips. Chop chop!"

    "Will you at least give me time to, oh, I don't know, replace the damn moped with something better?"

    "What? Why would you have to spend time on that?"

  2. Interesting analogy , Jon.
    Especially because like Jenga- the software does get wobbly and precarious- You just want to get it done anyhow -somehow

    Here is my take on the subject...

    I like to take the 'battle' on to the non-business manager's turf rather than explain to him the technical reasons in support of refactoring.

    Though refactoring doesn't introduce a new feature- it sets ground for newer features to come by in future.
    E.g You may refactor the UI and thus introduce newer technologies like AJAX down the road. By cleaning the datamodel- you may allow better deployment and hence more control to Services team.

    So basically what I mean is- establish support for refactoring by showing the business advantages for doing so- it could be a new feature or a grounds for new feature a or even that it will help improve quality and reduce time to market.

  3. Cool ... explanation,
    even you could consider the example of a old ( existing ) house and trying to re-model ( refactor ), vs re-building.

  4. Hi Jon,

    First of all, sorry for my English (i'm not native speaker), but I'll try to explain what I think about that.

    So, the first type of refactoring coming from legends :), very very very old code-base, original team disappeared and new team could not get in to that "damn" code :).

    The second one is more realistic - we need to introduce new features, new functionality and because of this we usually change the design.

    Well, the second point looks good for explanation.