Skip to content

Instantly share code, notes, and snippets.

@kinopyo
Created September 6, 2012 04:50
Show Gist options
  • Save kinopyo/3651371 to your computer and use it in GitHub Desktop.
Save kinopyo/3651371 to your computer and use it in GitHub Desktop.
Null Object Pattern example, extract from "Ben Orenstein - Refactoring from Good to Great, Boston Ruby August 2012" presentation. http://bostonrb.org/presentations/refactoring-a-live-coding-odyssey
require "ostruct"
class JobSite
attr_reader :contact
def initialize(location, contact)
@location = location
@contact = contact
end
def contact_name
if contact
contact.name
else
'no name'
end
end
def contact_phone
if contact
contact.phone
else
'no phone'
end
end
def email_contact(email)
if contact
contact.deliver_email(email)
end
end
end
class Contact < OpenStruct
def deliver_email(email)
# ...
end
end
require "ostruct"
class JobSite
attr_reader :contact
def initialize(location, contact)
@location = location
@contact = contact || NullContact.new
end
def contact_name
contact.name
end
def contact_phone
contact.phone
end
def email_contact(email)
contact.deliver_email(email)
end
end
# Null Object Pattern
class NullContact
def name
'no name'
end
def phone
'no phone'
end
def deliver_email
end
end
class Contact < OpenStruct
def deliver_email(email)
# ...
end
end
def initialize(location, contact)
@location = location
- @contact = contact
+ @contact = contact || NullContact.new
end
def contact_name
- if contact
- contact.name
- else
- 'no name'
- end
+ contact.name
end
def contact_phone
- if contact
- contact.phone
- else
- 'no phone'
- end
+ contact.phone
end
def email_contact(email)
- if contact
- contact.deliver_email(email)
- end
+ contact.deliver_email(email)
+ end
+end
+
+# Null Object Pattern
+class NullContact
+ def name
+ 'no name'
+ end
+
+ def phone
+ 'no phone'
+ end
+
+ def deliver_email
end
end
@jfeltesse
Copy link

what happens when your object has 100 methods? copy 100 times the definition? and what about maintenance (if a method signature changes you need to update both files) ? sure metaprogramming might help but I don't see the real value here...

contact ? contact.name : 'no name'

is short and simple enough to me.
Moreover, using rails it can become

contact.try(:name)

just my 2 cents.

@kinopyo
Copy link
Author

kinopyo commented Sep 7, 2012

yeah I agree with you, personally I don't see a time when I'll use it in real life, especially in Rails.

I pasted these because this approach, or so called Null Object Pattern is new to me. Kind of inspring despite how we're gonna use it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment