Redesigning existing code

Uncle Bob Martin has a post up called Wading through Code where he talks about becoming a better developer by reading someone else’s code.  The value of reading good code, or just plain different code, from someone else is obvious, and you’ll pick up plenty of coding strategems that way.  However, the first comment immediately fires back with “how does one learn to write better code by reading through a lot of really bad code?”

My answer is to try to redesign the code.  Figure out how I would design the system if I had been the one to build it.  Find a smell in the code, think up a possible refactoring to clean it up.  Look for duplication in the code and invent a new abstraction to eliminate the duplication. 

It’s mostly just a thought game, but it forces you to really get inside the existing code to understand what it does and look for the domain concepts of the code.  More than once I’ve ended up putting those design ideas into use when it became time to rewrite or at least refactor the legacy system.  It’s also a great way to get more practice in designing software.  I have reused design ideas from these mental exercises and abandoned projects many times on later projects.

I have a colleague who takes a very perverse pride in being able to wring meaning and function out of even the worst code.  It’s a valuable skill, because there’s a lot of nasty legacy code out there that’s too useful to throw out.  Supporting and changing bad code is expensive though.  Assuming that a rewrite is infeasible, the best choice is to improve the legacy code over time to extend its lifecycle and reduce the costs of working with it.

My contention is that you’ll never make substantial progress unless you’re constantly thinking about ways to improve the legacy code to improve coupling, testability, eliminate duplication, excise really ugly code, etc..  You never know when proposed changes to the legacy system will afford you the chance to make those improvements.

I’d recommend doing a little bit of this on your own code too.  I’ve never completed a system that I didn’t look back on and say “I wish I’d done xyz differently.”

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at
This entry was posted in Legacy Code. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Corey G

    Being a fan of TDD, Refactoring, and my friend that went to work at ThoughtWorks — In the past 3-4 yrs I’ve starting looking at existing code and just said to myself, “We can do this in a cleaner, more managable way”. More often than not, it works out to be much better than previously.

    I’m noticing however with “out-sourced” work[ers]. Most code is not well thoughout OO. It’s just as bad as procedural. Even worse, when you have an application with classes that span across all domains and have a different variable name for the same value in 4 different classes, etc.. So I starting to believe that knowing how to Refactor will become a very powerful skill in a developers toolbox. Might even need a certification for it (I just wanted to say that to see if Microsoft has spiders that look for lame ideas like this)..

  • Chad Myers

    Aint this post the truth.

    I’ve been struggling through the ring of fire trying to unlearn all I’ve learned and switch to a dependency-injected, IoC mode of thinking.

    I’m also doing MVP in ASP.NET which is really cool stuff and it’s working well.

    Throughout all this reading I’m doing, and then practically applying it all, I’ve started to come to a conclusion:

    Conditional statements (if, switch, etc) are a Code Smell. Not always bad, but mostly bad if they’re not inside the Subject Matter Expert class (I’m sure there’s a better term for that, but that’s how I think of it currently).

    It seems that if some class is making more than just a few token decisions, it’s got too much power and needs to be decoupled and smacked down a few rungs.

    Switch statements should be avoided in all but the most basic circumstances. I swear, the majority of my maintenance nightmare stories involve some sort of nasty switch or if/elseif/elseif/elseif/ad nauseum situation.

  • Eber Irigoyen

    “you’ll never make substantial progress unless you’re constantly thinking about ways to improve “…
    that’s a key point, is just a hard one to follow