Chris Johnston

Web development and design with a little VFX thrown in for fun
  • Home
  • About Me
  • Contact Me
  • Projects
  • Resume

Lesson from Object Bootcamp – The Null-Object Pattern

Published by Chris Johnston on February 27, 2007 02:32 pm under Application Development, Programming, ThoughtWorks

I thought I would share a few of the things that I learned while going through Object Bootcamp last week. The first, and probably the biggest thing was the idea of memory equivalence. This can be show easily by also showing another thing that I learned which was how to use the Null-Object design pattern. This is a pattern that I have read about, but have never really seen used until now.

The Null-Object pattern is used to return a null object instead of a null. The former is better since it removes the chance of encountering a NullPointerException. The idea is to return an object that basically does nothing, i.e., its methods simply return default, useless data. The trick is in how to implement this object.

Say we have an email object that represents an email address and can send an email when the appropriate method is called; however, the email address may or may not exist. So instead of returning null, we want to return a null-object when we do a search. So here is our email object:

public class email {
  private String emailAddress;

  public boolean sendEmail(String message) {
    // send out email using Javamail or something
  }
}

Now here is the same class utilizing the null-object pattern, the trick is the static instantiation.

public class Email {

  public static Email noEmailAddress() {
    public boolean sendEmail(String message) {
      return false;
    }
  };

  private String emailAddress;

  public boolean sendEmail(String message) {
    // send out email using Javamail or something
  }
}

The sensible default is to always answer false (i.e., the email was not sent) when sending the sendEmail() message to the Email object. This way, it does what we expect and doesn’t break anything.

*Update:* ignore the following since, although it does make the code more readable, it breaks with the intention of the null-object pattern. As pointed out to me in the first comment.

Another cool feature of using the null-object pattern is that we can now write code that looks like this:

if (returnedEmailAddress==noEmailAddress) {
  // do something about it
}

Instead of checking to see if the result is null.

if (returnedEmailAddress==null) { //do something }

This makes the code a lot more readable and understandable. Just by looking at the code, we can understand immediately what happened. The trick to this is that we only ever instantiate one noEmailAddress object. This allows us to check that the two references point to the same space in memory and results in a very nice equivalency check instead of having to use returnedEmailAddress.equals(noEmailAddress).

5 Comments so far

  1. Nat on February 27th, 2007

    The whole point of the Null Object pattern is that you *never* check if the object is null, you just call a method and it does the right thing — nothing if the object is “null” and something if the object is “real”.

    E.g. if you have statements like “if (returnedEmailAddress==noEmailAddress) {… ” in your code you are not following the Null Object pattern (or OO design principles) fully. The branches of the if statement should be moved into the appropriate implementors of the Email interface and the explicit conditional replaced by a polymorphic call.

  2. Chris Johnston on February 27th, 2007

    Good point. And I get to learn something else. I have updated my post and removed the last few bits to reflect your comment. I agree, the point of the pattern is to ensure that you do not need to check what was returned. You can simply assume that the returned object is good and rely on the defaults to prevent any problems.

  3. Nate on February 27th, 2007

    I would replace the ‘never’ with ‘never, except at your module boundary’. Returning a NullObject to someone outside of your module is at least as bad as returning a null. NullObjects are generally quite specialized to exactly the operations you need them to quietly ignore. As soon as someone needs to check for a NullObject or it makes your code complex, you’ve lost.

  4. Nate on February 27th, 2007

    Oh, and on your example: Java isn’t quite that concise, and having a method return it rather than a constant won’t ensure you have only one copy. I think this is what you meant:

    public class Email {
    public static final Email NONE = new Email() {
    public boolean sendEmail(String message) {
    return false;
    }
    };

    private String emailAddress;

    public boolean sendEmail(String message) {
    // send out email using Javamail or something
    }
    }

  5. Josh Graham on March 5th, 2007

    Hmmm.

    Nate’s example is nice for testing (stub-a-licious). Probably not nice for production code.

    Fail fast and NPE if there’s not a useful implementation. Defaulting to a null object seems rather dangerous and makes it harder to find subtle bugs.

    Use dependency injection of a “simple” or “does nothing” or “null” implementation is really really what you’re after. It should respond with “situation normal” just like a real implemenation would.

    In your scenario, if there was no mail sending aparatus available, the “null” emailer probably should behave like everything was fine. Returning false would indicate something should have happened but didn’t and the code needs to deal with it (Exceptions, anyone?). If you’ve explicitly wired in a “do nothing but be happy about it” implementation then it should return true and the code continues as everything has eventuated as desired.

    Perhaps. :)

Posting your comment.

  • Search

  • Categories

    • .NET (2)
    • Agile (41)
    • Apple Mac (15)
    • Application Development (124)
    • Articles (4)
    • ColdFusion (2)
    • Demo/Tutorial (3)
    • Eclipse (1)
    • Flash (6)
    • General (567)
    • Git (1)
    • Google (1)
    • Hibernate (4)
    • J2EE (39)
    • Java (111)
    • Java Frameworks (5)
    • Links (1)
    • Linux (33)
    • Miscellanous (2)
    • NetBeans (3)
    • News (10)
    • Open Source (6)
    • Photography (2)
    • Programming (33)
    • Python (1)
    • Ruby (27)
    • Ruby on Rails (14)
    • Ruby on Rails Web Apps (1)
    • Software (14)
    • Spring (4)
    • Teaching (1)
    • TeamDocs (6)
    • Technology (2)
    • Test Driven Development (1)
    • Thoughts (33)
    • ThoughtWorks (8)
    • Tips and Tricks (1)
    • User Experience (1)
    • Web Design (7)
    • Web Development (37)
    • Wicket (1)
  • Archives

    • September 2009 (1)
    • June 2009 (1)
    • May 2009 (1)
    • April 2009 (7)
    • March 2009 (2)
    • February 2009 (6)
    • January 2009 (4)
    • December 2008 (3)
    • October 2008 (1)
    • September 2008 (2)
    • August 2008 (6)
    • July 2008 (4)
    • June 2008 (1)
    • May 2008 (8)
    • April 2008 (7)
    • March 2008 (2)
    • February 2008 (1)
    • January 2008 (5)
    • December 2007 (3)
    • November 2007 (4)
    • October 2007 (5)
    • September 2007 (2)
    • August 2007 (3)
    • July 2007 (6)
    • June 2007 (5)
    • May 2007 (5)
    • April 2007 (5)
    • March 2007 (6)
    • February 2007 (9)
    • January 2007 (16)
    • December 2006 (6)
    • November 2006 (15)
    • October 2006 (17)
    • September 2006 (27)
    • August 2006 (22)
    • July 2006 (14)
    • June 2006 (10)
    • May 2006 (18)
    • April 2006 (3)
    • March 2006 (6)
    • February 2006 (15)
    • January 2006 (7)
    • December 2005 (11)
    • November 2005 (8)
    • October 2005 (18)
    • September 2005 (24)
    • August 2005 (18)
    • July 2005 (21)
    • June 2005 (14)
    • May 2005 (23)
    • April 2005 (18)
    • March 2005 (34)
    • February 2005 (27)
    • January 2005 (27)
    • December 2004 (15)
    • November 2004 (17)
    • October 2004 (20)
    • September 2004 (10)
    • August 2004 (21)
    • July 2004 (9)
    • June 2004 (11)
    • May 2004 (4)
    • April 2004 (15)
    • March 2004 (12)
    • February 2004 (7)
    • January 2004 (17)
    • December 2003 (11)
    • November 2003 (8)
    • October 2003 (12)
    • September 2003 (12)
    • August 2003 (12)
    • July 2003 (23)
    • June 2003 (22)
    • May 2003 (14)
    • April 2003 (9)
    • March 2003 (22)
    • February 2003 (24)
    • January 2003 (32)
    • December 2002 (11)
    • November 2002 (16)
    • October 2002 (10)
    • September 2002 (9)
    • August 2002 (13)
  • Pages

    • About Me
    • Contact Me
    • Projects
    • Resume

Copyright © 2010 Chris Johnston
WordPress Theme based on Light Theme