Two IF statements to Avoid

Posted: September 13, 2010 by Ash Mishra in Design, Programming

After 15 years of writing software, I’ve accumulated several thoughts on software design.

I didn’t go to school primarily for Software engineering, and I haven’t spent as much time reading heavy books on the subject as I would like.  Most of my career comes from hands-on experience, and learning from both successes and past reflection.  Indeed the phrase Design Pattern was a foreign one to me until a decade ago when I started realising some of what I had been practicising had terms coined for them.

Through experience, I’ve gravitated to several favourite patterns and key concepts.  On a new project these are the MVC (Model-View-Controller) pattern, the DRY (don’t repeat yourself) principle, the use of Convention over Configuration, the use of reflection, protocols, state engines, recursion, and remote configuration.

Sounds a little like the kitchen sink – doesn’t it?

But sophisticated maintainable software almost completely relies on design.  While there are many facets to design, one that I focus on heavily on is how reusable code is.

I hesitate to say this can be achieved by reading design pattern books, or the use of technical skills, as several times I have made the mistake of repeating these errors.


All too often, we developers find ourselves knee deep in projects that have been underestimated and overcommitted.  In this new state of reality, where the demands of the customer are louder than everything else, the first impulse is to code and forget the principles behind what makes good software design.  So suddently you catch yourself adding an IF statement in code which previously was pristine and had only a single branch of flow.  But this should be your first clue that perhaps it’s time to think about refactoring the design into a higher level concept.

By higher level, I mean the use of Superclasses or Protocols.  There should never be special-case exceptions in software code, and common practices such as using IF statements to determine the logic to proceed, are really just hacks, tricks, and frankly not a shortcut, or temporary.  These quick solutions usually get baked in.

But what if it’s just for a slight exception to the code to get to code-completion; and well this project isn’t probably going to be touched again.  Isn’t that ok?  Well the answer to that is subjective, and depends very much on the task at hand.

The truth is, it’s very rare that any piece of software is perfect, and it’s even rarer that a project ever ends.  It may have stages where development is idle – even for several years – but software that is used on an ongoing basis, will eventually have requirements for extension.  And thats when our special exceptions can cause havoc.

So its in those hours of greatest need, those where the project is due and the customer is saying we need it now, that we need to tread carefully with the code we write.  And thats where self-discipline comes into play.

Discipline begins to waver on long projects when developers are exhausted and there seems to be no light at the end of the tunnel.  It’s these moments, where the sum of exhaustion, frustration, pressure, morale starts to cloud judgement – and instead of good design, we practice rapid coding.  And rapid code, rarely is good code.

So be aware of your own level of frustration and exhaustion on a project, and act accordingly.  Sometimes a project is malleable and things can be left out.  Other times, well it depends on the situation; and there is no way out but to code rapidly.

IF I might need this…

Another common practice I have encountered repeatedly over the years, is one I thankfully recognise and do not practice myself.  This may be because I like to build my software as lean as possible; and I tend to refactor and abstract code when the design warrants it.

A number of projects that I have joined, have gone the opposite direction.  The lead developer has read a dozen books on the technology being used; and on the onset of a project have decided to add what they think are good design principles.

If I might need to localise this application, I should write code to support that right now.  If the application may be too slow, I should optimise this section right now.

Yet another IF statement.

There’s a fine line between not enough design, and overdesign.  As a developer I need to be constantly walking this line.

Good software design is about how much is put into, as how much is left out, and to paraphrase a very well known quote: “premature optimization is the root of all evil.”

Premature design is also a source of evil.  It can complicate, obfuscate, and even hinder the design of code before it has been written.  This is because so much effort is being put into following unneeded design elements that might or might not be useful.

Many times the design of an application is not apparent on the onset of coding.  By leaving out the nice-to-haves, code is leaner, less noisy, and much easier to refactor.

So be aware that the design principles we put into our software, should first and foremost be the ones that accomplish building the application so that it achieves its major functional needs.  The nice-to-haves can be in many cases be added after.

  1. Aaron Hilton says:

    Good article Ash! I’m currently in a position of primary design. Constantly fighting over-design, yet need to break the development down into tasks that are estimate-able. It’s a royal pain, but here’s a useful addendum to designing and planning any project.

    So far Story Points has been the best system of estimation we’ve had so far.

    How it works is 1 story point is considered 1 developer’s ideal day of programming. We developers estimate in half day increments for sets of tasks, and make sure nothing goes beyond 3 story points. If anything is over 3 story points, then we know we haven’t broken down the task sufficiently. Most task break-down should hover around 0.5-1.5 story points. We add up all the story points, and multiply by a factor. 12 Hours per story point has worked out really well so far. Finally we lay down a timeline and budget based on those hours.

    With tasks broken down to this level, our timelines are a whole lot more accountable. If something significant changes we can see all our tasks change too. This makes change requests or development roadblocks easy to bring up sooner. The only downside is it’s a whole lot more work up front to breakdown the tasks, and it’s possible for big chunks of our breakdown to get tossed out the window if an early assumption was made incorrectly.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s