Writing Effective “Special Case Pattern” and “Null Object Pattern”

Handling null can be problematic in code organization and management. So, there are two very common patterns used by experienced developers now and then. One is “Null object pattern”, where you return an object which states a missing object, and another is “Special Case Pattern”. This article is to “How you can write effective objects for those patterns and why you should use them instead of returning null or throwing exceptions”

Definitions and Reasons:

 

Wiki: Null Object Pattern

The basic idea is “not to return null” so that you don’t need to immediately handle it in the caller block. But there are some valid points stated here which may lead you to think this pattern is useless.

null pointers vs. Null Object Pattern

A more specialized/generalized pattern was stated by Martin Fowler here which is a super set of null pattern:

Martin Fowler: Special Case Pattern

Now, how you use that pattern so that you can avoid problems stated in stackexchange and still benefit from these patterns. I will write some ideas that would help to write those effectively. But first you need to read those articles, because I am gonna write in light of their examples.

Reasons found from many resources:

  1. Null can be a real value. So, it can create ambiguity in overall design of the software.
  2. Even experienced developers forget to check null because of busy schedule or deeply thinking about the algorithm. So, NullPointerException, can bring nightmare.
  3. Null needs to be handled immediately. This can lead to tangled flows of code. If it’s a expected value, you handle it one way, if it’s a invalid value, you handle it another way. Your code will need comments, needing comment means non-clear code. And you will need unnecessary refactoring to make them clean later!

 

Practice

1. Don’t return null from object’s functions:

 

Class MissingCustomer implements Customer{

   public Long getId() {

       return null; // NEVER

   }

}

If you do this, you are getting into the same null problem. And more importantly you will create more problematic code by passing this “null” to other objects/methods. NEVER DO THIS!

2. Don’t return special values

 

Class MissingCustomer  implements Customer{

   public Long getId() {

       return 0; // NEVER

   }

}

0 is also an invalid value and will cause you similar problems as returning null. The future calls with this value can indeed generate more nulls.

3. Throw a meaningful and special exception

 

Class MissingCustomer  implements Customer {

   public Long getId() throws MissingCustomerException {

       throw new MissingCustomerException();

   }

}

So from the expected behaviour methods you should through an exception.

What if you had inconsistent data where you actually had an ID, but couldn’t create an object? You can easily save the ID into the MissingCustomer object and attach the ID to Exception you threw!

“is it an exceptional case that the object is not found”? You need to answer this first if you just want to throw an exception if an object is not found. Because an exceptional case is “exceptional”. There might be practical situations where an object, even if it does not exist, may have default behaviour. For this, here is my 4th suggestion:

4. Add default behaviour

 

Class MissingSprite  implements Sprite {

   public void draw() {

       // draw nothing or a generic something.

   }

}

A sprite can be missing for read failure while you are playing a game. The game still should not crash while you are playing. Still you can keep your application logic pretty simple and clean. You may call these disposable objects. Even a long list of objects may have disposable objects in case of eventually consistent or inconsistent database. Iterating through the list may become very easy and clean if you use these patterns. Just remember to design the special class well.

5. Add isValid/isNull method and rarely call that!

Always calling isValid/isNull makes the code dirty. Try to minimize this call. If you need to relate this object to another, only then you should do it.

Advertisements

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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