Null Object Pattern

An object that implements the interface and does nothing, so callers stop checking for null. Know when absence should be invisible, when it must be loud, and how the pattern differs from Optional and nullable types.

Overview

The Null Object pattern replaces 'nothing' with an object that has the right interface and safe, empty behavior. Instead of every caller writing if logger is not None: logger.log(...), the code is given a NullLogger whose log does nothing, and the check disappears from every call site.

The pattern is credited to Bobby Woolf's paper 'Null Object' in *Pattern Languages of Program Design 3* (1998), and Martin Fowler's refactoring catalog lists Introduce Null Object as the older name of Introduce Special Case: a class that stands in for a special value and answers with defaults. Tony Hoare, who added the null reference to ALGOL W in 1965, called it his billion-dollar mistake in a 2009 talk; this pattern is one of the ways code avoids handing null around.

Interviewers want to see the mechanism (same interface, empty methods), one judgment call (a missing logger may be silent; a missing payment gateway must not be), and the comparison with the language tools that make absence visible instead of invisible: Optional in Java, nullable types in Kotlin.

The mechanism

  • The interface — What callers rely on: log(message)
  • The real object — Does the work
  • The null object — Implements every method with a safe no-op or a neutral value (empty list, zero, false)
  • The caller — Depends on the interface and never asks which one it holds

Before and after

Before, absence is a special case at every use. After, absence is one class, chosen once where the service is built.

Python's own standard library ships one: logging.NullHandler is a handler that does no formatting and no output, provided so that a library can attach a handler and stay silent until the application configures logging.

Where the pattern fits, and where it hides bugs

The pattern makes absence invisible. That is right when doing nothing is a correct outcome, and wrong when doing nothing is a failure that should stop the program.

  • Logger, metrics reporter — Nothing is recorded, program is still right — Null object
  • Cache — Every read misses, program is still right — Null object
  • Payment gateway — Money is not moved; silence loses money — Raise at construction
  • Repository lookup by id — The record may not exist and the caller must react — Optional, a nullable type, or None with a check
  • User permissions — No permissions means every check answers false — Null object, if 'no access' is the intended default

Null Object versus Optional and nullable types

These are two different questions. The Null Object pattern asks how a service behaves when a collaborator is absent. Optional and nullable types ask how a caller finds out that a value is absent.

  • Absence is — Hidden inside an object — Visible in the return type — Visible in the type
  • Caller does — Nothing special — map, orElse, orElseThrow, ifPresent — Safe call ?., Elvis ?:, or a null check the compiler demands
  • Best for — Services and dependencies — Return values where 'no result' is a real outcome — Any value that may be absent
  • Documented intent — A no-op stand-in — The Java docs say it is mainly meant as a method return type, and an Optional variable should never itself be null — Compile-time null safety

What you will be able to do

  • Define the pattern with its three pieces and show the before/after in code.
  • Decide, for a given dependency, whether silence is correct or a hidden bug.
  • Tell the pattern apart from Optional and nullable types in one sentence.
  • Connect it to interface size: a small interface makes a null object cheap to write.
  • Name a real one in a standard library.

Interview questions

  • Explain the Null Object pattern with a concrete example.
  • When should you use a Null Object and when Optional or a nullable type?
  • What are the risks of the Null Object pattern, and how do you limit them?
  • How does the Null Object pattern relate to the Interface Segregation Principle?
  • Show a Null Object that returns neutral values, not just no-ops.

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio