Null Object Pattern
A design is far better when there are no exceptions. Whenever you write an if statement, Nyan Cat cries.
Yesterday I remembered this blog quote when I faced a common situation handling nested hashes in Ruby.
What if I want to get some of that data and use it to manually instantiate a
Company entity? Wll, attributes for that entity are not nested like the hash is:
That’s not the most beautiful piece of code, but it works if–and only–if all keys are present. If not
fetch will complain. You can say, “But what if we use
 method instead of
fetch?” Well, if the
address key is missing in our
hash, the code
hash[:address][:line_1] will throw a
NoMethodError for NilClass. Not ideal.
What now? “Add an
if, it will fix that.” Mmmm… yes, it will solve the problem, but do you remember the quote at the beginning of this post? I want to avoid adding
if statements to this piece of code. This is where the Null Object pattern enters.
I used a very simple implementation of this pattern just to satisfy cases like this one. We can use it in many different ways and have a lot of flexibility, I just wanted to avoid the
NoMethodError being thrown again.
# null_object.rb class NullObject def method_missing(*args, &block) nil end end # company.rb address = hash.fetch(:address, NullObject.new) Company.new( name: hash.fetch(:company_name), address_line_1: address.fetch(:line_1), address_line_2: address.fetch(:line_2), city: address.fetch(:city), state: address.fetch(:state) )
This way the
NullObject instance is just nullifying my call to
fetch, because I don’t have that
:address key. This improved my design, simplified my code, and made it safer.
Why don’t you go ahead give it a try? It might be as helpful for you as it was for me. Here I created my own implementation of this pattern, a very simple one, no fanciness needed, but if you want something more sophisticated check out Naughy, by Avdi Grimm.