Write Less Code, by Writting Intellingently

I am currently working on a project, and when I say currently, I mean it literally, as in right now. But I think it is worth making a parenthesis to write this entry. I just wanted to point out the huge difference that can be made in the code you write, if you do it more intelligently.

Lets look for example at how we might write some piece of code:

var addSomething, addSomethingElse
function start(){
  addSomething = B('a[href="something"]')
  addSomethingElse = B('a[href="something-else"]')

  if(addSomething.length > 0){
    prepareAddSomething();
  }
  if(addSomethingElse.length > 0){
    prepareAddSomethingElse();
  }
}

function prepareSometing(){
  addSomething.click(handleClick('something'))
}

function prepareSometingElse(){
  addSomethingElse.click(handleClick('something-else'))
}

function handleClick(type){
  switch(type){
    case 'something':
      return someFunc;
    break;
    case 'something-else':
      return someOtherFunc;
    break;
  }
}

This piece of code has some nice “features”. For example, it divides all the work in functions that do one task only. It has a nice “dispatcher” that handles adding the click handlers to each element.In my case, instead of returning someFunc and someOtherFunc in the dispatcher, I execute another function, which then returns the function that will be listening for the events. So, as you can see there are some good things about this piece of code. However, it is too long. Many of the code lines are repetitive, and it is too verbose to my taste. We can simplify this code by identifying the pieces that repeat too much.

The firs thing we see, is that instead of having prepareAddSomething, and prepareAddSomethingElse, we can have a single prepare function which can handle the task that this function handle:

var addSomething, addSomethingElse
function start(){
  addSomething = B('a[href="#something"]')
  addSomethingElse = B('a[href="#something-else"]')

  if(addSomething.length > 0){
    prepare(addSomething)
  }
  if(addSomethingElse.length > 0){
    prepare(addSomethingElse)
  }
}

function prepare(reference){
  reference.click(handleClick(reference.attr('href').replace('#','')))
}

function handleClick(type){
  switch(type){
    case 'something':
      return someFunc;
    break;
    case 'something-else':
      return someOtherFunc;
    break;
  }
}

We have successfully replaced two functions with one, and the code still does the same thing. Notice how we realized that the argument that we pass to handleClick is the value of the href attribute of the anchor elements without the hash (#), and used that to our advantage.

Next, we notice that we only want to run prepare if the collections of elements returned by the function B (which is just an alias of jQuery’s $) is greater than zero. We can also get rid of the double if statements, and replace them with a single if:

var addSomething, addSomethingElse
function start(){
  addSomething = B('a[href="#something"]')
  addSomethingElse = B('a[href="#something-else"]')

  prepare(addSomething)
  prepare(addSomethingElse)
}

function prepare(reference){
  if(reference.length > 0)
    reference.click(handleClick(reference.attr('href').replace('#','')))
}

function handleClick(type){
  switch(type){
    case 'something':
      return someFunc;
    break;
    case 'something-else':
      return someOtherFunc;
    break;
  }
}

Since the idea here is to write less code, we are not using the curly braces “{ and }” since they are optional in this situation.

Now we have a shorter version of our code, that is still very readable, and that does the same thing as the original code. All we had to do was look at it, find the things that get repeated over and over again, and write more general functions.

This is just a quick note I wanted to make, maybe it inspires you to look at your code and try to find out where you can make it shorter.

One last thing you should notice is how it would be really hard to make one single prepare function if we didn’t have that little dispatcher function (handleClick). That is one of the reasons I like using those kind of functions.