When it's Design Hell

What do you do when your project already sucks, and it’s already late, and the design you’ve been committed to is Hell?

I have this thing I do; I sort of call it “Emergency Agile.” Note that it’s completely wrong by normal standards but it kind of gets projects off the proverbial dime.

You totally want to read more about this, and you will, if you get onto my eZine mailing list. You get a complete mailing about once a month, with articles and links and special offers that help you do your job, as well a quick note every week or so with something funny or interesting. Do you need more stress? No? Then this is for you.

Anyway, here’s how I deal with Design Hell.

First thing

You know what? Projects get messed up for good reason. Software design and implementation is really difficult, defintely more difficult than your management grasps. I keep getting called ostensibly because this or that team member is a jerk or over his head or not working hard enough. This very rarely turns out to be true. The world of software development is full of clever, hard-working, professional people.

Nobody does a bad design on purpose. Got it?

Second thing

Almost always, there is some particularly big obstacle, but it can be at any conceptual level. Finding that level is the key. Is it as simple and direct as a specific, deep bug? That’s awesome, because you can find it and fix it and be on your way.

As a software practitioner, one of the coolest and most useful skills you can develop is that of reading other people’s code. It’s cool because it’s difficult, combining technical kung-fu with a rough-and-ready psychology. It’s useful because it prevents having to rewrite the entire system from scratch. In particular, it’s good to make a separate model of the code, something you can put in prose or on a whiteboard. Keep refining that model as you discover more and more about the existing code. Quite soon some patterns will emerge and repeat themselves.

Sometimes underlying it all is an overall design issue–like a messy class hierarchy that’s hard for normal people to follow, or a key data structure that nobody’s quite explained. One time I saw a four-dimensional array in JavaScript that drove everything in the application but had no descriptive comments at all!

Or you might find that the toolset is completely disconnected from the purpose of the application, such as n-tier applications done (in this decade) with Visual Basic 6 in the middle. (Sure you can make it work, but what a slog.) The original developers may have had great knowledge and the best intentions, but they were stuck working without implementation inheritance and a fairly weak standard class library.

In any case,the point is to answer the very general question: “What is it that we’re looking at?” Is it a solid design with a lot of implementation bugs? Is it overly ambitious? Did the first developer fail to understand inheritance, or when to use composition or interfaces instead? Is it way too highly coupled? (I see that one a lot.)

Big Ball of Mud

Very likely, though, your design issue is that there is no design. This is often referred to as the Big Ball of Mud pattern: “a casually, even haphazardly, structured system.” What a pain! These systems are particularly hard to understand and modify. The good news is that the Ball of Mud gives you free rein to reformat and refactor the code; since there is no design, you can’t possibly break the design.

Next thing

Whether you’ve got a Big Ball of Mud, or just badly suited design, the key is to use what you know about what’s wrong to create quick and incremental design improvements. There’s more than one way to accomplish that, and the right way depends so much on the details of your project, but here are a few wicked short-term techniques for getting the code under control:

  • Pair-program the easy parts first.
  • Collect selected globals into a Singleton class, then control access to them.
  • Run over the code with ReSharper or similar.
  • Pair-program the hard parts first.
  • If the design was too ambitious, extract the simplest parts and keep them.
  • Intentionally break highly coupled code. Stitch it back together with loose coupling.
  • Document the data structures, even if you have to guess a little.
  • Profile the code to find out what sections are never called, and remove them.
  • Impose naming conventions, which sometimes help reveal patterns in the code.

When you do this, the design of the existing code isn’t so much created as discovered and shaped as you go along–less like architecture, more like sculpting.

Back to the first thing

If you make design improvements quickly as you go, you’ll doubtless find things the previous developers did right. Take a moment to appreciate their skull sweat, even as you regret the things they did wrong. Software development is an inherently difficult and frustrating task. There’s nothing wrong with sharing a laugh over some really bad code, but remember the goal is to build maximum value with what you have.

Good luck getting out of Design Hell! Do it one little bit at a time, but quickly.