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.

Monday, August 22, 2011

DCI in short - Can you fly that helicopter?

Trinity is the object, Matrix is the Context, HelicopterPilot is the role (injected runtime in Matrix).


It's obviously a simplification but overall I think this metaphor expresses the idea of DCI very well. Trinity represents the D (Data), Matrix represents the C (Context) and HelicopterPilot role along with the Helicopter itself (and other objects) represent the I (Interaction).

This example is good as it shows how your software can evolve. Your objects don't need to know upfront that they will play some roles, it's all runtime (as with Trinity and the helicopter).

Can you fly that helicopter?

Wednesday, August 17, 2011

Tracing aspect for a Rails application

Aspects are modules for crosscutting concerns. Typical crosscutting concerns are: persistence, tracing changes (history), permissions and logging.

Aspect Oriented Programming is not a popular topic in the Ruby community. Partially, it's because Ruby gives us some AOP constructs out-of-the-box (open classes) but also due to some built-in mechanisms in Rails - like filters and callbacks which serve as the dynamic part of AOP.

I think that there are scenarios in which traditional AOP can be very useful. Today, I'm going to show you how to implement logging of chosen method calls, without touching the methods itself.

Aquarium seems to be the best AOP framework with Ruby.

Installation

#the first part is only needed if you want to use ruby 1.9
#otherwise just put gem "aquarium" into the Gemfile and run "bundle install"

cd vendor/gems
git clone https://github.com/deanwampler/Aquarium.git
cd Aquarium
git checkout 1.9.1-port

# edit Gemfile and add:
gem 'aquarium', "0.0.0", :path => 'vendor/gems/Aquarium/aquarium'
bundle install

Creating an aspect


Create config/initializers/tracing_aspect.rb and paste:
require 'aquarium'
include Aquarium::Aspects
Aspect.new :around, :calls_to => :all_methods, 
    :for_types => [User],
    :method_options => :exclude_ancestor_methods do |jp, obj, *args|
  begin
    names = "#{jp.target_type.name}##{jp.method_name}"
    p "Entering: #{names}: args = #{args.inspect}"
    jp.proceed
  ensure
    p "Leaving:  #{names}: args = #{args.inspect}"
  end 
end

If you now run the tests or just use your app, you should see all the method calls on User objects being logged to the output.

I hope it works fine for you, let me know in case of problems.

Sunday, August 14, 2011

DCI patterns - how to write DCI contexts in Ruby

After my previous post about DCI and Rails some people contacted me regarding best DCI patterns. As the topic of DCI is still new I didn't want to engage into creating patterns - I think they should emerge from existing projects. The idea of DCI seems to propagate in the Ruby/Rails circles - there was a RailsConf talk on this topic and more DCI blog posts appear. If you haven't heard about DCI yet, please read my last post first: DCI and Rails.

Recently I got an email from Pavel Mitin in which he describes his pattern for creating DCI contexts in Ruby. As this pattern matches exactly with my approach I think it's worth sharing and recommending as a pattern.

This example consists of two base classes - Human and Address. Objects of the Human class can play two roles: Policeman and Thief, while the Address can sometime play the role of FakeAddress.

Splitting classes into roles and injecting roles runtime is only a small part of DCI. The bigger thing is the idea of Contexts, which you can also think like a User Story or a Use Case (as a big simplification). In Pavel's example we have the context of the Policeman arresting the Thief. In this case the thief object has the address object extended with a FakeAddress.

This example shows some interesting concepts. As you see we're not replacing the thief's address - as in this world we think that humans have one address. What we're doing is extending the address object and "overwrite" the to_s method runtime in the context of arresting. I assume here the to_s method abstracts the thing that the thief is "saying" to the policeman.

The most important part, however is the way the context class is written. ArrestContext is a class with a constructor and the execute method. It's the constructor job to wire all the relevant roles to the actors. Once the roles are injected the execute method can start the "procedure".


There are still questions remaining regarding the contexts. Who should access the context classes? Let's assume that we have an application object in our project which represents the whole system and that it's a web Rails app. Should the application object (a model) know about the contexts?

Here are some options:

1. the application object has access to all the possible contexts. The controller just calls methods like: application.register_new_user(..) and it's the application that initializes the context.

2. controller has the knowledge about the specific "global" context it handles: NewUserContext.new(..).execute

3. controllers as we know them (Rails) disappear, the wiring between actions and context takes place in a configuration file.

All of the Ruby DCI examples so far seem a little bit verbose. It's because they are direct translation from languages that are not as dynamic as Ruby. It's not my goal at the moment to create a nicer API but I'm pretty sure we can come up with nicer syntax. Can you help? Especially, I think that the context classes can become some kind of configuration files - what role to inject to which objects, then which method starts the "procedure".

I'd love to know your opinion on this topic. Does it make sense to you? Is the DCI concept clear to you?

Friday, July 22, 2011

Stop hating Java

I noticed that in the Ruby community “Java” is a synonym of pure evilness. It’s often used as an argument against some techniques.

“It’s Java all the way”


“If you drop static methods, then welcome to Java and its billions of useless factories.”


“Your mention of ‘factories’ gives me nightmares about Java-style over/premature abstraction where you need to interact with (and therefore understand) WAY too many different classes to get anything done.”

Those are some quotes that come from only one discussion triggered by Nick, me and Michal only because our ideas sounded a bit Java-like.

History

Part of the Java-hate comes from the historical reasons. When Rails appeared lots of Java people switched to it as it solved some of the problems with Java. I was one of them.

Rails was simpler than the existing Java frameworks. It let us solve most of the problems much faster than with Java. Ruby as a language was and still is a big advantage. Its syntax is more concise. Even though I still prefer Rails than Java based frameworks I don’t get why so many Rails people simply hate Java.

Java and XML

I always disliked the XML impact on the Java frameworks. It didn’t come from nowhere, though, let’s be fair. Java as a languages is not as readable as Ruby, so it wasn’t perfect for configuration. Yaml wasn’t popular and JSON was still not really mature back in 2000. Something had to be chosen and that was XML. What would you do better back then?

It doesn’t mean that whenever some Java-like idea is presented then somehow you have to be scared that you’d have to use XML again. Let’s try not to be biased and look at Java ideas without the XML bias.

Java and over-abstraction

Yes, often Java frameworks were very abstract and overgeneralized. Again, it was a result of Java lack of dynamic features. Whenever you needed a pluggable system in your code you had to abstract away some concepts in order to make it work. Ruby lets us do it much easier and that’s cool.

Java and good things

There is lots of good things that came from Java to the Rails world. Most of the TDD/BDD stuff comes from Java. Refactoring came to us from Java [UPDATE: What I mean is that those techniques came to the Rails world *through* the Java world, they're not originally from Java]. They became popular in the Rails world. That’s cool. There are other techniques that are great, but somehow didn’t get so popular:

Dependency Injection and Inversion of Control

These two techniques are great for many reasons. They suggest that you should expose your dependencies in the constructor or through setters. It reduces the usage of globals and static methods and simplifies testing. In my opinion they result in much better object oriented design.

POJO - Plain Old Java Objects

This is one of the places where I felt I made a step back when entered Rails from Java. In Java there was a clear trend that your business classes should be clear from any framework dirtiness. Persistence was configured and injected from outside (or through annotations). When your business classes are not polluted with framework stuff it’s much easier to test them in isolation. In Rails there are many tries but no good solution on how to test models without a database.

Aspect Oriented Programming

I was involved in the AOP movement in my Java life. AOP was the tool that let you intercept method calls and run some crosscutting code from one place. If you needed logging of method calls and params, it was just 3 lines of code in an aspect and all of your method calls were traced. Similarly, it was possible to handle persistence with AOP. Another part of AOP was composing classes from smaller pieces. Fortunately, this part now appears in the Ruby world in form of the DCI architecture. The dynamic part (interception of methods) didn’t get very popular. We have some limited AOP with filters in Rails controllers and callbacks in Rails models, but we could go further and use it for persistence or for logging.

Let’s stop the hate

It’s cool that we, as a community, strongly identify with some techniques. What I’d love to see is more tolerance for other technologies.

There are smart things in the Java world but we have to be open to reuse what’s most cool and replace the bad parts with Ruby awesomeness. When someone starts his talk with “In Java this problem is solved by …” don’t laugh and interrupt with quotes like “OMG, XML and factories again”. It didn’t happen only to me. I have seen this behavior at Ruby conferences very often. It's childish.

Many good things came from the Java world - we should love them for that.


There are more large Java systems than Ruby ones. They abstract for reasons. They use IoC and DI for good reasons. AOP is awesome when used in a good way. Let's learn more from Java - it will help us once we work more with larger systems and codebases. They already learnt their lessons.

[Discussion on Hacker News: http://news.ycombinator.com/item?id=2793227 ]

If you read this far you should Follow andrzejkrzywda on Twitter and subscribe to my RSS. You can also buy me a beer at the wroc_love.rb conference. I'm one of the organizers.

Wednesday, July 20, 2011

Yes, Nick - class methods are evil

My friend Nick has just posted an interesting article about the usage of class methods. The article is really good, go read it first and then come back.

Are class methods evil?

In my opinion class methods are almost always a wrong approach to a problem. It’s not wrong as in “it doesn’t work” but wrong as “we can make it better”.

ActiveRecord and Rails

I blame the ActiveRecord pattern for the current class methods problem. Every Rails application I see is full of globals which are often results or causes of class methods. The problem with ActiveRecord is that it forces you to think in terms of sql tables. Almost every table exists as a class with lots of class methods that let you access the data from this table.

I mean methods like:
User.find(id)
User.all
etc.

Can we do better?

One of the things Nick suggested is using user_factory. Overall he’s right, but I don’t think user_factory is a good name for that. We’re not producing users in our app, right? The users live in the context of our app. Is it a shop or a game or maybe a portal? Then create a class for that. This is your “factory”. Once you have it, always access users through this object. Not only users, you can do the same with products, prizes etc.

Instead of User.find(4) you now have game.users.find(4) or better game.find_user(4). You still gain from the ActiveRecord methods, without using the class methods, though.

How to implement the app class?

There are two ways that I’m aware of. Both are not ideal, mostly due to the way ActiveRecord works, but in my opinion they improve the code quality.

1. Create an ActiveRecord model for that.

If your app is a game then create a model called Game with the associated table (games). Yes, it will possibly have only one record and yes it may add some overhead to the queries that are generated by the ActiveRecord framework. Thanks to that however you may have only one “singleton/global” in your app.

class Game
  has_many :users
  has_many :prizes
  ....
end
I usually put the implementation in the ApplicationController and have something like:

def game
  Game.find_by_name(“Music Challenge”)
end

Then, in every other controller I can access the game object and find all the data I need through its scope.

2. Non-ActiveRecord class

The other way assumes that you hide the globals in this class. It can be done in many different ways. One of them is:

class Shop

  def products
    Product.all
  end

  def find_product(id)
    Product.find(id)
  end
end
What’s my choice?

Overall, I prefer the first way. It has a nice side-effect that once you have the game/shop model you can easily turn your application from a single game to a platform of games (which we actually did in one project, but that's another story).

I also try hard to find the way out of the ActiveRecord and sql/nosql dependencies and go into a pure OOP direction with madeleine/prevayler-like tools.

What’s your choice? Do you see the problem with class methods?


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