Backbone – when used properly…

Sunday, October 27, 2013

it keeps one’s head out of one’s butt.

This little gem was the first JavaScript MVC like tool that caught my eye. It has a very vibrant community and seems to have reached certain maturity level. More importantly it is so small library that everyone can grok its source code fully in couple of hours. And yet I haven’t actually used it in any project even thought I had couple of occasions.

I guess it was partially because I had read ThoughtWorks technology radar October 2012 edition where author’s claim that:

Backbone.js is a great example of an abstraction pushed too far (…) We find that it blurs the framework and model too much, forcing either bad architectural decisions or elaborate framework hackery in order to preserve sanity.

Back then I had to make a quick decision which framework/library to use, if any, on a project that I started working on and the article steered my away from using Backbone.js. Just for the record the project was developed with Angular.js.

Forming my own opinion

It really bugged me why the technology radar authors stated such a harsh opinion about a tool that has caught some much attention. It seemed even more interesting because I haven’t found a follow up or a more elaborate and concrete comment about the decision to put Backbone.js on hold. I did however find some time to do a simple demo for a presentation I gave on our company internal conference.

The demo I built has only 2 pages. First one shows how to make a page more interactive with a filtered table and couple of elements that trigger the same behaviour. Second view was created just to see how easy it is to make use of html push state. The source code is available on github.

Due to its minimalistic nature it’s really easy to start working with Backbone. The documentation is easy to follow and if you don’t find enough explanation you can always dive into reading the source. The library let’s you choose how you would like to render you views. Out of the box it provides support for client side templates by leveraging underscore.js.

Views are in fact the main force that drives code control. As there is no typical Controller I found it hard to decide where to put some of the initialization logic. For simple cases Router might be a good choice however as the application grows I pretty sure this approach would not be sufficient. It also means that you are now responsible for composition of smaller views into a complete page. I know this problem is solvable in many ways – Derick Bailey’s plugin Marionette is an excellent addition that fills the gaps not provided by Backbone.

What I find most disturbing is the way we attach events to DOM elements by providing selectors. I use this approach on daily basis in a project solely based on jQuery but there are several shortcomings that in my opinion make it hard to apply to large applications. First of all it means that you typically would add artificial CSS classes to elements. This isn’t bad at first as long as you use those classes only for attaching events and not for providing ways to style your application. An important implication follows –it’s nearly impossible to have a UI designer to work on html and CSS parts without breaking application behaviour. You can however mitigate this by establishing some rules and naming conventions. For instance that all artificial classes used to attach events are prefixed with ‘js-‘ and shall not be used inside CSS files.

Prefer composition over inheritance.

The most important part of the presentation logic are models, view models or presentation models (depending on a pattern flavour you’re using). I think it should be the main place where your application behaviour is defined. Whenever a tool that I’m using is trying to push some structure over me in that single place I immediately get suspicious. Unfortunately it’s not different in Backbone. The way you define and implement your models inside Backbone app is through deriving from base class provided by the library. By doing this you gain many of the commonly required features of model object like filtering, validation and even associations. It speeds up a development a lot especially when you are in need of this commonly requested functionality like form editing in CRUD applications.

However, from my experience, preferring inheritance over composition hurts the most when used to built model part of an client side MVC. I guess this is true for me mainly because I often change the structure and the way different parts of model talk to each other way more often than views and controllers interactions. Having a predefined structure, imposed by framework, limits ways you can define the model and this sometimes leads to pain points that are hard to overcome. In general inheritance is much stronger form of coupling than composition even in a language as malleable as JavaScript so I think that my observations might be true for others too. As all ways this is a question of getting the right balance between having a lot of features ready and waiting for you and keeping you model as flexible as possible to survive the harsh realities of requirement changes.

Don’t listen to me, try it yourself…

I’ve pointed some of, in my opinion, weak points of Backbone. I realize that I might be wrong in some parts and have missed out some important aspects. The fact that the community behind the tool is so active and from what I see always willing to help some newbies can probably out weight cons I’ve listed. I think Backbone is a very effective tool for many programmers out there – it just does fully adhere to my rules.

However when choosing a framework to use on a project one should not be focussed on finding good or bad opinions on the web. I think its much better to spent a week or couple of days with the team actually using the tool to build real features. This can give an immense feedback generated by the project team within actual context – one that you would never get reading reviews on the web.