Thursday, January 31, 2008

Rails: Aspect-Oriented Programming / Decorator Pattern

Rails implements the Decorator in such an unusual way that its worth asking if it is a good idea or not. In my opinion it isn't. I don't see any advantages in Rails' implementation - do you?

But I do see several disadvantages. The biggest one is that its removes an obvious extension point from Rails. Once two methods are linked together using Ruby's alias method you can't break them apart. For example, if A aliases B then you can't insert C between them. This might not seem like a big deal, but for some extensions it quite important. For example, when I wrote our REST controller implementation last year I struggled mightily to fit it into Rails aliases method calls and finally gave up and took a different approach. Its worth noting that its often possible to work around this problem since Ruby is such a flexible language. Instead of adding a new decorator, in many cases you can replace the original method to achieve what you want. Its not nearly as elegant, but it usually does the trick.

A second disadvantage is that it complicates Rails architecture. What's the difference between a decorator and a filter? Nothing. By using the Decorator pattern you could merge Rail's filter functionality with its method chaining functionality, thereby reducing its overall code base.

A third disadvantage, albeit a minor one, is that the method chains Rails creates are hidden. You can't look at a single piece of code, or configuration file, and see the method chains. The closest is action_controller.rb and action_view.rb, but I can't get a handle on a chain object at runtime and say "please print yourself on STDOUT so I can see what is happening."

Charlie Savage: Rails' Unusual Architecture