Nothing is something
- Sandi Metz1
Null objects surface hidden assumptions making code easier to reason about and to change. Consider the number
0. Initially a mathematical placeholder,
0 was imbued with meaning allowing all numbers to be used in new ways.
By working with numbers as they approach zero, calculus was born without which we wouldn't have physics, engineering, and many aspects of economics and finance.
Takeaway 0: Applications have abstractions like
0 that reveal themselves through the absence of code.
Consider a lab that may or may not have an experiment running.
lab.try(:experiment) # is: lab && lab.experiment # is: lab.nil? ? '' : lab.experiment # is: lab == nil ? '' : lab.experiment # is: lab.is_a?(NilClass) ? '' : lab.experiment # is: # which ultimately is: if lab.is_a?(NilClass) '' else lab.experiment end
Its easy to forget that each of these expressions is a conditional and that conditionals are implicit type checks.
Takeaway 1: Type checking hampers the full power of objects.
Rabbits of OOP - Conditionals
if (object type is NilClass) # Caller supplied behavior else # Caller sends message to collaborator end
if burdens the caller with knowledge of what behavior to provide when the object is a
NilClass. Callers should know only what message to send to whom. As callers multiply, this burden can overwhelm applications like a herd of rabbits. Instead of fostering the local rabbit population, use a null object to isolate and provide the behavior.
Takeaway 2: Behavior supplied by a caller is a hidden null object.
The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.
- Alan Kay3
Our programs are easier to maintain, reuse, and extend when we rely on message passing. A recognition that conditionals are a subtle form of type checking and that callers should not supply default behavior surface the need for an object that can stand-in in the absence of a real object. Next time you write a conditional or reach for
try! consider if there is a null object that could better serve your needs.
Photo By NASA/GSFC/METI/ERSDAC/JAROS, and U.S./Japan ASTER Science Team [Public domain], via Wikimedia Commons