donderdag 19 maart 2009

A simple refactor step

Here's a short snippet from me to think about. Say we have a some code which retrieves a list of orders from a datasource. The part of the application using this functionality looks like this:
public class OrderProvider
{
public ICollection<Order> GetOrdersFor(Customer someCustomer)
{
ICollection<Order> orders = CallSomethingHereToFetchOrders();
return orders;
}
}


	ICollection<Order> orderlist = OrderProvider.GetOrdersFor(someCustomer);

if(orderlist == null || orderlist.Count == 0)
{

//something is happening here//
}
else
{
//something else is happening here//
}


At a glance, someone I showed this to said there was nothing inherently wrong to this snippet. I care to disagree. What’s wrong here, in my opinion, is that the provider doesn’t have a unambiguous behavior as far as an empty list is concerned. There should either return an empty collection by default, or throw an exception if it somehow gets a null value to return. A simple implementation would be as follows.



public class OrderProvider
{
public ICollection<Order> GetOrdersFor(Customer someCustomer)
{
ICollection<Order> orders = CallSomethingHereToFetchOrders();
return orders ?? new List<order>();
}
}


	ICollection<Order> orderlist = OrderProvider.GetOrdersFor(someCustomer);

if(orderlist.Count == 0)
{

//something is happening here//
}
else
{
//something else is happening here//
}


Notice we split up the complexity of the if statement in the calling code, reducing the amount of possible conditions that match the case. We also moved the responsibility of checking the validity of the model to where it belongs: the code actually BUILDING the model we’re going to use. By doing small refactoring operations like these, it’s easy to maintain a good separation of concerns. The calling code, whatever it will do (maybe… print the orders one by one to paper, or show some nice statistics on screen), will never have to worry about null checks on things like this. Now we can focus on the happy part of that bit of code!

zaterdag 14 maart 2009

Driving instructions for software development

I just had a moment of deeper understanding in how real life guidelines apply to software development as well (as far as software development isn't real life of course).
When I was taking driving lessons for my license a while ago, my driving instructor gave me a few tips, which with a little creative reasoning apply to software development as well:
  1. Be decisive. Don't hesitate, do what you have to do. When you make a decision, follow through! Don't wait when you don't need to, just do it!
    In sofware development: When in a situation that seems difficult, find a way to solve it or a way around.
  2. When in doubt, don't. Although this might seem to conflict with rule one, it really doesn't. When you think something won't fit, it probably won't. You'll break rule one if you do something when you're in doubt.
    In software development: When you can get a project you're not sure about, try to not take it if at all possible.
  3. Plan ahead. When going somewhere you've never been before (different country, or in software: new technique) do some research about the rules, applications, dos and don'ts.
    In software development: Do some research on the techniques you will have to use before applying them.
  4. Aim for where you want to go, not for what you try to avoid. Set your focus on the goal, not the pitfalls!
    In software development: Solve the hard parts of your problem first, or (again) find a good way around them.
Seems like I got more out of my driving lessons than just my license! Thanks instructor dude!

zaterdag 7 maart 2009

Refactoring spaghetti PHP

So, for my current job I (together with two peers) write-slash-maintain a moderately big stack of PHP code. It’s written in a typical PHP fashion: (almost) no object-oriented principles, a bad attempt of separating presentation and business logic, code duplication all over the place, and, currently my biggest nemesis, zealous usage of the ‘global’ keyword. What is the global keyword you ask?

By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function.

What this means is that I can define a variable in the global scope of the script, and then pull it into my function without having to pass it as an argument. A small example:

<?php

$myGlobalVar = “Hello World”;

function Hello()
{
global $myGlobalVar;
echo $myGlobalVar;
}

Hello();

?>

This code shows how to use the global keyword to basically get a variable from the global scope into the scope of the function being called. Another (in my opinion, better) option, is to pass the variable being used as an argument to the function. Another example from my cookbook:

<?php

$myVar = “Hello World”;

function Hello($gonnaPrintThis)
{
echo $gonnaPrintThis;
}

Hello($myVar);

?>

Even though the code is different, the output is the same. We’ve gotten rid of the global keyword, thus making the function reusable and more robust. Not only that, but if I wanted to test it in isolation, that would be very easy as well.

Now, most examples you see, these ones included, are very simple, and don’t really show the pain of bad design. Imagine the following situation, where globals are misused.

file1.php
<?php

// bunch of code here

?>

file2.php
<?php
require_once("file1.php");

// bunch of code here

?>

file3.php
<?php
require_once("file2.php");

// bunch of code here

function HelloAgain()
{
global $someGlobal;
echo $someGlobal;
}
?>

File 3, containing our function HelloAgain, requires file 2, which in turn requires file 1. Obviously, those files contain more than just some variables being set. In this situation, there’s absolutely NO way to determine the current state of the global variable $someGlobal at the moment the function HelloAgain is being called. The global could’ve been set (OR NOT!) in any other place imaginable. This my friends, is what I call a maintenance nightmare. One which you can not solve in a few minutes once it has settled itself firmly within the darkest corners of your codebase.

HOWEVER! With a few simple steps, you can isolate the scope of your global. I realize some OO purists will burn me for this, but this situation is easily solved by using a singleton pattern. A singleton pattern is a well known object-oriented pattern, which ensures that one, and only one instance of a certain object exists at any given time. A simple implementation in PHP 5.x (courtesy of wikipedia.org):

<?php
class Singleton
{

private static $instance;

protected function __construct() { }

public function __clone() {
trigger_error('Clone is not allowed.', E_USER_ERROR);
}

public function __wakeup() {
trigger_error('Deserializing is not allowed.', E_USER_ERROR);
}

//This method must be static, and must return an instance of the object if the object
//does not already exist.
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self;
}
return self::$instance;
}

public funtion getMyVar() {
return "Hello world! I'm still here!";
}
}

function Hello()
{
$printVar = Singleton::getInstance()->getMyVar();
echo $printVar;
}

Hello();
// or //

function HelloAgain($gonnaPrintThis)
{
echo $gonnaPrintThis;
}

$myVar = Singleton::getInstance()->getMyVar();
HelloAgain($myVar);

?>

Using this pattern to wrap a global variable might seem overkill, and on the other hand, not a big improvement over using globals. But it is. Making the global variable you need a return value for a function on your singleton object not only encapsulates the variable, it also opens up all sorts of options. You can later on easily add logic to fetch the value from the database, cache it and what not. You can refactor some more, and eventually create a coherent, object-oriented solution instead of a big lump of meaningless code. But first and foremost: You are now back in control!

woensdag 4 maart 2009

Jenga Programming

I’m coining a new programming discipline, called Jenga Programming, or Jenga Driven Design (JDD). It’s something I see happening all the time, and it’s driving me crazy now and then.

For those of you who don’t know what Jenga is:

Jenga is a game of physical and mental skill, marketed by Hasbro, in which players remove blocks from a tower and put them on top. The word jenga is derived from kujenga, the Swahili verb "to build"; jenga! is the imperative form. (http://en.wikipedia.org/wiki/Jenga)

Basically what you do is you start with a solid tower, and keep removing parts and adding them to the top of the tower until it falls over. It’s a simple game, and quite fun to play. In programming however, this is arguably one of the best ways to create a maintenance nightmare.

At a glance, JDD looks promising. You start with a big solid block of code, and simply start removing the bits that are not needed to keep it standing. After that, you’re adding new things to the top. Sounds like iterative development and refactoring to me. If it was that simple, I wouldn’t have come up with this theory.

So what do I mean with JDD? We’ll dive a bit deeper into Jenga for that.

When you play Jenga, you remove blocks by gut feeling. When you’re removing a block you’re free to bump around the other blocks, or leave a block half removed if you think it will topple the tower. After you removed the block, usually you simply put it on the top in such a way that the tower won’t fall over. The only thing that matters when putting the block on the top is making sure the rest of the tower doesn’t come crashing down.

Superimposing this view of the game on ‘the game of software development’ will make it painfully clear where this goes wrong:

When you’re doing proper refactoring you (ideally) make sure that the code is covered by well-written tests, and that the functionality of the code is known. This is not the case when doing JDD: you remove bits which you think do nothing useful.

When you add new functionality to your application you make sure you know why you’re adding the specific functionality, and that it written well. When playing the JDD game, you add functionality whenever someone asks for it (adding a multitude of meaningless options/settings, anyone?). You don’t really care about the rest of the system, as long as it works.

Of course, JDD doesn’t work so well in compiled languages like Java, C or C#. When you remove something that’s still used, your compiler will cry out in pain, and you won’t be able to deploy the application into the wild. That’s why JDD is a typical (anti)pattern seen in PHP (and other script languages) development. Now, I’m not saying PHP is bad (well, not in this blog at least), but it does tend to let programmers do things like this. I blame it on the programmer though.

To summarize, JDD is programming without a solid plan, adding and removing things without a lot of thought. This is not to be confused with agile/extreme programming methods, where there IS a lot of thought going on.  So next time you encounter an application which falls over after a simple change, there’s only one thing to say:

 

JENGA!