Saturday, June 4, 2011

design patterns - null object pattern

As we know, if conditional statement is one thing that hurts the program readability. NULL object is also one approach to reduce your application's if condition statements. We are all familiar with these kind of code:

$user = $userDao->getUserById($id);
//For objects, i personally like to use instanceof for type checking
//but more usually, other programmers simply check $user !== null.
if ($user instanceof UserObject) {
       //do some logic with $user here
       echo $user->getName();
} else {
       //do some other things if $user is null
      echo 'user not exists';
}


As we can see, we usually use if conditional statement to check if $user is null or not, and then behaves differently based on the checking result. This kind of if statement checking could be all over the whole application. NULL object is here to help, for simplicity, i will ignore the interface part, let's check the code:

class User implements iUser
{
       private $_name;
       public function getName() {
               return $this->_name;
       }
}

class NullUser implements iUser
{
       public function getName() {
               return 'not exists';
       }
} class UserDao {         public function getUserById($id) {                 //query the database or do what ever to get the user                 $user = $this->find($id);                 if ($user === null) {                        return new NullUser();                 }                 return $user;         } } //Now your domain logic will become quite straight forward and more readable: $user = $userDao->getUserById($id);
echo $user->getName();


Now you can see how NULL object pattern can help simplify your business logic, however, you must be very careful with using this pattern. Although it simplifies your domain logic and increases readability, it does complicate your design and maintenance. And if a programmer is not aware of a NULL object implementation, he may redundant the null test, or he may really want to do some different thing if the object is null. Null object may also bring you issues when it comes to CURD operation, for example:
if ($user !== null) {
    //db query:
    $posts= $articleDao->getUserPosts($user);
}
//if we use null object, we will do the db query anyway,
//which might not be necessary
$posts= $articleDao->getUserPosts($user);

Personally, i totally agree that we should try to reduce if conditional statement in our application, particularly in business domain. But when it comes to checking if an object is null or not, i feel that i can accept that, because usually, the logic is not complex when an object is null, or even there is no logic when an object is null, for example:

$user = $userDao->getUserById($id);
if ($user instanceof UserObject) {
       //do some logic with $user here
       echo $user->getName();
//that is it, we don't have to do anything when $user is null




No comments: