Today I Learned

Decorator Pattern in Ruby with SimpleDelegator

The Decorator Pattern allows us to chain new behaviours to objects without modifying the underlying objects. It is an application of the Open/Closed Principle. This pattern is useful for example when we need to tack on logging, monitoring, and other non-functional requirements to objects.

In Java or C# this can be achieved using interfaces. In Ruby, we can use the SimpleDelegator class to achieve this:

require "delegate"

class FooDecorator < SimpleDelegator
  def bar
    "This is a decorated #{__getobj__.bar}"
  end
end

class Foo
  def bar
    "bar"
  end

  def fiz
    "Fiz"
  end
end

decorated = FooDecorator.new(Foo.new)
puts decorated.bar # outputs "This is a decorated bar"
puts decorated.fiz # outputs "Fiz"

double_decorated = FooDecorator.new(FooDecorator.new(Foo.new))
puts double_decorated.bar # outputs "This is a decorated This is a decorated bar"

Sources: