Architecture & DesignWorking with Design Patterns: Null Object

Working with Design Patterns: Null Object

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

The original Design Patterns book [Gamma] presented 23 patterns, solutions to problems commonly observed in software development. In the years after the book was released, pattern-happy software developers mined numerous additional patterns from their experiences. The community saw the release of several books on patterns as well as conferences where they discussed patterns.

The null object pattern found its way into the literature in the form of a 1996 article by Bobby Woolf, “The Null Object Pattern.” Its basic goal is to find a way to encapsulate the notion of how to “do nothing” in code [Woolf]. In a simpler time, we might have referred to the null object pattern as a stub.

So what does it mean to “do nothing” in code? No doubt you’ve seen rampant code like this:

Request request = getRequest(command);
if (request != null) {
   // do something useful
}

or:

public void doSomethingUseful(Request request) {
   if (request == null) {
      logger.warning("null command");
   }
   // do the real stuff
}

Thus, “do nothing” if the request reference ends up being null. Checking whether or not a reference is null quickly becomes a paranoid exercise. Every argument and every field gets checked before code in a method dare use it.

Often, this paranoia is a symptom of a real problem. Someone’s code somewhere upstream allowed for a null reference to be propagated. Often these defects are hard to pinpoint, so the short-term reaction is to introduce null checks. “At least it won’t generate a NullPointerException!”

Unfortunately, masking symptoms never solves real problems. Simply put, the best thing to do is to determine the earliest point at which a reference could be null, and then stifle it there. The remainder of your application can merrily go on its way, assuming that an argument, field, or local variable always points to an object, and never to null.

So, how do you “stifle it?” What if there is a possibility that an object can’t refer to anything that the application truly needs? That’s where the null object pattern comes in.

A null object hinges on the power of polymorphism in OO. It is simply an object of a class type that does nothing by default. “Does nothing” might mean that the object logs an appropriate message if necessary, or otherwise does nothing truly useful from an application standpoint.

Here is the same code example I presented earlier, still insisting on its paranoid null check:

Request request = getRequest(command);
if (request != null) {
   // do something useful with request
}

Request is simply an interface type:

interface Request {
   void execute();
}

The job of the getRequest method is to return a Request object:

private Request getRequest(String command) {
   if (command.equals("A"))
      return new ARequest();
   if (command.equals("B"))
      return new BRequest();
   if (command.equals("C"))
      return new CRequest();
   return null;
}

Well, that’s the source of the problem right there! If the command String matches no suitable expected value, getRequest returns null.

A small change to getRequest introduces the null object pattern.

private Request getRequest(String command) {
   if (command.equals("A"))
      return new ARequest();
   if (command.equals("B"))
      return new BRequest();
   if (command.equals("C"))
      return new CRequest();
   return new NullRequest();
}

Instead of returning null, getRequest returns an object of type NullRequest. NullRequest implements the Request interface, and can execute a logging statement when the execute method gets called. Here’s a possible implementation for NullRequest:

class NullRequest implements Request {
   public void execute() {
      logger.warning("executed null command");
   }
}

The significant point is that it is impossible for the Request reference to ever be null. The if-null checks, which can considerably clutter application code, disappear.

Is the null object pattern fail-safe? Well, of course not; it’s always possible to do something stupid in code. But implementing it will give you much better control over the source of the problem, and will simplify your coding efforts overall:

Request request = getRequest(command);
// do something useful with request

No more if statement!

The null object pattern isn’t always necessary—sometimes you do want to do something severe (in other words, not “do nothing”) upon encountering a null. It’s best suited where the null event itself is not catastrophic, and where a suitable default value can be assigned or simple default action can be taken.

Figure 1: Implementation of the null object pattern.

References

  • [Gamma] Gamma, E., et. al. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional, 1995.
  • [Woolf] Woolf, Bobby. “The Null Object Pattern,” 1996.

About the Author

Jeff Langr is a veteran software developer celebrating his 25th year of professional software development. He’s authored two books and dozens of published articles on software development, including Agile Java: Crafting Code With Test-Driven Development (Prentice Hall) in 2005. You can find out more about Jeff at his site, http://langrsoft.com, or you can contact him via email at jeff at langrsoft.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories