Sunday, September 25, 2011

Rails is not MVC

There is a terminology problem in the Rails community.

Everyone promotes Rails as a MVC framework. I did that as well. However, the truth is that Rails represents the Model2 architecture. It's not MVC. 

I know it's just a definition issue. Maybe we shouldn't care. It wasn't really a problem until recently. We see the rise of the JavaScript MVC topic, which is an awesome thing. The browser clients with its JS engines can have a real MVC, as opposed to Model2.

OK, so what's the difference?

In short, we're talking about MVC when a model can notify (through the Observer pattern) the views about the changes. It's not possible in a classical Rails app (it's possible when you use WebSockets, Pusher or a similar technology, but it's not so popular yet.). MVC was popular in desktop apps.

On the other hand, Model2 is exactly what we do with Rails. We don't notify the views from the model, the controller simply passes the model data to the views and handles the html generation which is then sent to the browser.

There's an interesting pattern evolving recently that a Rails app simply serves as a backend for a mobile app and all it does is exposing a JSON/REST API. It's similar to Model2, but instead of generating HTML it generates JSON. Still, it's not MVC.

You can read more about UI architectures in this article by Martin Fowler

Why is it important?

It's becoming an issue now, because we start talking more about the JavaScript MVC. The JavaScript MVC is a real MVC. The models can easily notify the views. Often, when you talk to people being introduced to the JS MVC they seem to be confused and try to implement the Model2 pattern on the client side, which in my opinion is ridiculous.

What shall we do about the Model2 and MVC confusion?

I see three choices.

The first one is to say that MVC changed its original meaning and Model2 can also be called MVC. In that case we can start using terms like "classic MVC" or "real MVC" for the old MVC. This is what is happening now, but I don't think that changing definitions is a good idea. It brings even more confusion.

The second way is to promote the fact that Rails represents a Model2 architecture and MVC is reserved to, well, MVC. It's going to be hard, but we will keep the definitions stable.

The third way is to just ignore the confusion. Who cares?

I decided to go with the second option. What's the best way in your opinion?

 If you read this far you should Follow andrzejkrzywda on Twitter and subscribe to my RSS.

Saturday, September 24, 2011

3 steps to MVC in JavaScript

  1. Read this article MVC Architecture for JavaScript Applications by Peter Michaux. It's a must-read and it nicely explains how the observer pattern works in the classic MVC. (Keep in mind that the MVC that you know from Rails/Django is a limited MVC, that's a topic for another post).
  2. Use Backbone and Underscore to handle events or roll your own observer mechanism (as described in Peter's article).
  3. (optional) Use CoffeeScript to make your code prettier.
Let me quote Peter Michaux:

In a nutshell the classic MVC architecture work like this. There is a model that is at the heart of the whole thing. If the model changes, it notifies its observers that a change occurred. The view is the stuff you can see and the view observes the model. When the view is notified that the model has changed, the view changes its appearance. The user can interact with the view (e.g. clicking stuff) but the view doesn’t know what to do. So the view tells the controller what the user did and assumes the controller knows what to do. The controller appropriately changes the model. And around and around it goes.

In the GameBoxed platform, we have a Monopoly-like Facebook game. There's a concept of a player (this is the model). A player, after rolling a dice, can receive points and when he does we need to update the player-details box.

When the page is loaded (our games are one-page apps, no full reloads), the Monopoly object is initialized. It's a facade object responsible for initializing models, views and controllers and wiring them together.

At some point thanks to some users actions the player.addPoints method is called which triggers the "player:updated" event with some arguments. Thanks to the controller (the bind method), the PlayerView object is notified that something interesting happened and the view updates the html (with some jquery helpers).

This pattern is very useful and can be used in most of the typical UI scenarios. Let me know what you think about it.
 If you read this far you should Follow andrzejkrzywda on Twitter and subscribe to my RSS.