Why decorate objects instead of using inheritance?
It’s a more dynamic, flexible and transparent alternative to subclassing. There’s several different ways of using the decorator pattern in Ruby, but I’m just going to show the module/extend
approach. You can read about other decorator techniques in Dan Croak’s blog post.
Use a module and extend to add instance methods on an object. This will still maintain the ability to use super as demonstrated in this trivial example:
class Report def number_of_pages 10 end end module CustomerAdmendment def number_of_pages super + 5 end end module AdminAdmendment def number_of_pages super + 1 end end report = Report.new report.number_of_pages # => 10 report.extend(CustomerAdmendment).number_of_pages # => 15 report.extend(AdminAdmendment).number_of_pages # => 16
With the module/extend
technique we can maintain the original interface and delegate through all the decorators.