November 09, 2009

Refactoring code smell

I work every day with PHP, developing management tools for the company where I work, but when I accepted this job I was a pure noob in this language. In fact I was hired for some C++ programming, but soon my tasks evolved so that wherever there's code, I was there too. So, learning PHP was the logical evolution in this case.

As you can imagine, being a PHP developer fresh from the oven, I ended up committing many atrocities in my code. And now is when, with some more maturity and knowledge, I can detect, by sense of smell, where those design flaws are. It's a fact, bad code smells.

Searching for the light

Well, my early days of PHP were all a mess of "write and test" so even the maintenance of my own code is little better than a nightmare with ninja killer rabbits. The skills take time to develop as you're learning. But then, one day, you're illuminated by finding "The Path".

Change "The Path" with functions, objects, inheritance, aggregation, design patterns, MVC, reflection... whichever fits best. It's hammer time, and everything around seems like a nail. You browse through all your finished projects, changing things to match your "new mood", so you and your (old) code are in communion. But adding no value to the old applications.

Then, one day, a new "The Path" (there's always one more) enters your life, illuminating it from another point of view, and all your code begins to smell like a horde of skunks bathing in a sewer. Face it, you've entered an endless loop. Welcome to the real world.

A nightmare to remember

I've been in the programming world since 1994 and I've been hit by tons of bugs, mistakes and bad habits, some (tons) made by me, some not. While maintaining others' code, more often than not I found scripts that follow the lovely paradigm of "spaggetti code". No classes involved. Not even a f****g function. Nothing. Zero... Nada. That was GREAT.

Have you heard about the "$i++; // increases $i" comment?
I've seen one of those too. Not so funny, actually, IRL. I have no idea yet of what it does exactly.

Enter Refactoring

Refactoring is the tool we need in this cases. In words of Wikipedia, refactoring is the process of changing a computer program's internal structure without modifying its external functional behavior or existing functionality, in order to improve internal quality attributes of the software. In my own words, refactoring is to improve code so you won't go crazy when adding new functionalities.

Refactoring is not a new science. I think when the first programmer had to mantain others' code, refactoring was, more or less, invented. But I think I'm right saying that it was Martin Fowler with his book Refactoring: Improving the Design of Existing Code who put more efforts to make it a standard.

From things as simple as to change the name of a local variable to as sophisticated as replacing an enum with a strategy pattern, every tool in the box exists to make your code more readable. To the extent that there is no need to comment the code: it speaks for itself.

Refactoring applied

Which of the following two do you prefer?

// Transform user input from celsius to fahrenheit
$a = f($argv[1]);
$celsius = $argv[1];
$result = convertCelsiusToFahrenheit($celsius);

This is a quite simple example. Of course, Fowler's book is tons more interesting than this, but I hope this one delves into the open wounds left by some developers. If refactoring today, spending two hours, you save three tomorrow when adding functionality, will it be worthwile? I bet yes, but... that's my point, not my boss'.

Although I wonder if I have not found yet another "The Path" and all this is just another iteration of the loop...