Gabriel Dehan - Life is a Design Pattern Archive Pages Categories Tags

Now presenting SimpleDecorator

10 July 2012

So. I just finished the first version of the SimpleDecorator gem, now in 0.2.0. You can find it on Github, or on Rubygems.

What the hell is a decorator ?

Well, of course, a design pattern.

A decorator (pattern from [GOF]) allows you to add additional or specific behavior to an object instance, by wrapping this instance and providing new methods. Decorators are an easy way to provide a peculiar interface in a given context.

SimpleDecorator allows you to quickly implement Decorators in your application.

A true decorator

SimpleDecorator decorators are true decorators :

  class User
    def foo
      'bar'
    end
  end

  class Decorator < SimpleDecorator

  end

  user_decorator = Decorator.new(User.new)
  user_decorator.foo
  # => 'bar'
  
    class User
      def initialize; @count = 1 end

      def count
        @count
      end
    end

    class CountDecorator < SimpleDecorator
     def count
       @component.count + 1
     end
    end

    class TripleCountDecorator < SimpleDecorator
      def count
        @component.count * 3
      end
    end

    user = User.new
    user.count
    # => 1

    CountDecorator.new(CountDecorator.new(user)).count
    # => 3

    TripleCountDecorator.new(CountDecorator.new(user)).count
    # => 6
  
    class User; end
    class Decorator < SimpleDecorator; end
    class OtherDecorator < SimpleDecorator; end

    user = User.new
    decorator = Decorator.new(OtherDecorator.new(user))
    decorator.class
    # => User
    decorator.instance_of? User
    # => true
    decorator == user
    # => true
  

Installation

gem install simple-decorator

Usage

To create a decorator, simply inherit from SimpleDecorator.

class Decorator < SimpleDecorator
end

Then, you just need to wrap your object inside your Decorator class

class Foobar; end
# Decorator#new takes the instance you want to decorate as an argument
Decorator.new(Foobar.new)

It will give you access to the following instance methods : source, decorated which will return decorated object.

Inside your Decorator class, you can access the decorated object through the instance variable @component

class Foobar
  def foo
    'bar'
  end
end

class Decorator < SimpleDecorator
  def foo
    'foo' + @component.foo
  end
end

Decorator.new(Foobar.new).foo
# => 'foobar'
blog comments powered by Disqus
Fork me on GitHub