Refactoring Ruby: Introduce Null Object

Jon Lunsford
1 min readSep 10, 2018

--

Introduce Null Object is a great refactoring tool when you find yourself checking for nil too often. nil checks are often signs of much larger problems, as it violates Tell, Don’t Ask, and results in defensive, bug prone programming. Let’s take a look at a simple example of refactoring nil checks:

This Movie class is incredibly defensive, it goes to great lengths to ensure its account actually exists. Why should that responsibility fall on Movie? It would be much better for Movie to just assume it has an account OR something resembling an account. Let’s Introduce Null Object:

We have gotten rid of all conditions defending against nil and introduced one that always returns an Account like object:

def account
@account ||= NullAccount.new
end

Let’s run through the exact steps to take when applying Introduce Null Object:

  1. Identify conditions that check for nil, that are defending against objects potentially not existing, for example:
def rent
# nil check
unless account.nil?
account.charge(@price)
end
end

2. Create an object that acts like the one you are checking for as nil. Specifically, create a new class and define all of the methods that are expected to be there, for example:

class NullAccount
def charge(_price)
"No Charge"
end
end

3. Finally, substitute the null object when the expected one does not exist, for example:

Class Movie
...
def account
@account ||= NullAccount.new
end
end

Null objects are great at replacing conditional logic and making code more readable, as you don’t have to think through all of the different branches conditions introduce.

--

--

Jon Lunsford

Engineer @convertkit, programming enthusiast, father, and musician