Decorators are great - especially for building Ruby on Rails applications. They help separate the functionality from your models that some would consider “not core”. Ruby has a neat class called SimpleDelegator that we’ve been using to implement the decorator pattern. It’s clean, simple, attractive, and good with children which makes it a great candidate for this type of work. So let’s use it!
Lets say we have a
Person class with
#last_name attributes and we want to add a
#full_name method to this
class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name, @last_name = first_name, last_name end end
PersonDecorator that inherits from SimpleDelegator
And add our
class PersonDecorator < SimpleDelegator def full_name first_name + " " + last_name end end
So there is our decorator. But how would one actually use this? Actual use could look something like this:
Create our person object
person = Person.new('Joe', 'Hashrocket') person.first_name #=> 'Joe' person.last_name #=> 'Hashrocket' person.full_name #=> Method_Missing error
Decorate our person object
decorated_person = PersonDecorator.new(person) decorated_person.first_name #=> 'Joe' decorated_person.last_name #=> 'Hashrocket' decorated_person.full_name #=> 'Joe Hashrocket'
All SimpleDelegator is really doing is giving you method missing. Good stuff…
Now, I want to add a way to handle collections with this decorator. That is something often done with decorators. So, let’s add the class method `.wrap to this decorator. Our final version looks like this:
class PersonDecorator < SimpleDelegator def self.wrap(collection) collection.map do |obj| new obj end end def full_name first_name + " " + last_name end end
And that’s it! Have fun with your new decorator. Of course, there are many other ways to use SimpleDelegator. And there are just as many ways to implement the decorator pattern but I think SimpleDelegator is a pretty clean solution. But, it seems to be lacking in documentation department. Hopefully, this helps you gain a better understanding of SimpleDelegator.