Yoan Blanc’s weblog

Another lost swiss guy

Lessons from the Desktop to the Browsers

Yoan BlancMon, 30 Jun 2008, , , , ,

There were a lot of buzz recently about Sproutcore and Objective-C, a desktop architecture and language from the Apple platform that are adapted (or ported) to the JavaScript world. There is one great idea in Cocoa (built using Objective-C): yes it’s MVC but I want to talk about the Key-Value Observer. It offers a great abstraction for creating RIA from my point of view, but let’s start at the beginning.

aHtmlElement.onclick = function() { } formerly DOM level 0 is how you can handle native events in a very simple manner. I reminds me the C# delegates (that are using the += operator thus). Very simple and useful (but only one at the time, so very restrictive).

DOM level 1 introduces the addEventListener (or attachEvent for MSIE). I’m sure that the Java-guys will reminds the java.util.EventListener that you are using everywhere in any AWT/Swing application. The main difference is that JavaScript works at the function level and not object one. Java is not a functional languae.

Then some JavaScript framework/libraries offers a different kind of handling events. YUI, Dojo or jQuery have interesting ones. The great advantages of messages passing over function calls is that you separate the producer from the consumer (decoupling) and become more robust; if no one care about a message, it’s simply lost, but if something linke ten differents processes cares about it, they will for sure get it.

If you made a little bit of Qt®, Dojo have the connect method: dojo.connect(myObject, "onclick", function() {}); It’s still DOM level 0 method overloading, not very clean but simple. It has the advantage to works with non-native events (or with any functions call in that particular case).

YUI pandora box contains the CustomEvent, a very simple implementation of the Gang of Four (GoF) Observer pattern. It’s used in more or less in every single YUI widget.

var event = new YAHOO.util.CustomEvent("my type");
event.subscribe(function(type, data){
  alert(type + ": " +data)
});
event.fire("Hello World!");

jQuery has also a custom event handling system included. It’s very powerful and kind of no so documented. It reminds me the GObject signal used by GTK.

$(document).
  bind("my-type", function(event, data) {
    alert(event.type + ": " + data);
  }).
  triggerHandler("my-type", ["Hello World!"]);
    

I’d like to see a centralized system for messaging passing. I toke example on how Bayeux is made, some XMPP parts too, and wrote a pubsub class. It has the advantage that you don’t have to keep track of the object that manages the events and can subscribe to meta-channels (using the star *).

new pubsub().
  subscribe("/test/first", function(data) {
    alert("first got: "+data);
  }).
  subscribe("/test/second", function(data) {
    alert("second got:" + data);
  }).
  subscribe("/test/*", function(data) {
    alert("a message has been sent: "+data);
  }).
  publish("/test/first", [1]).
  publish("/test/second", [2]).
  publish("/test/third", [3]);

Now, what are offering Sproutcore or Objective-J to JavaScript? Key-Value Observer. That means you aren’t creating specific custom events, or channels but will observe objects’ values directly. It’s a very simple to do, the only trade off is to access them with getters and setters only (which sucks).

var label = function(name, value) {
  this.name = name||"";
  this.value = value||"";
};
// label inherits from observable
label.prototype = new observable();
label.constructor = label;

// you can also chain the followings.
var my_label = new label("my label");

my_label.observe("value", function(value) {
  alert(this.name + " is: " + value);
});

my_label.set("value", "Hello World!");

With all those tools, it’s very easy to imagine a complex rich internet application made of independent modules. Those modules don’t know each other directly, gets notified when something they are looking for happens. You can transform it into a MVC-like architecture with one kind of module for each type; displaying with HTML/CSS, reacting to HTML events, reacting to asynchronous events like XHR, storing data information.

All those issues have been handled by desktop software for years. I think it’s time to learn from it and get the best in terms of simplicity, reliability and strength. It’s also a lot easier to unit test small modules or to create brilliant mash-ups upon them. Being unobtrusive is maybe still the first step that many JavaScript applications have to face (with event delegation all over the place), the second one could be to not act as spaghetti code with as few cross references as possible. Rich internet application is becoming serious, so make sure it’s also as kind as possible to everyone, with ARIA for example.

La planète JavaScript a bougé (voire tremblé) récemment avec les annonces faites par Apple concernant Sproutcore (qui selon certain part en guerre contre Adobe Flash, je ne partage pas cette avis) ou 280 slides et leur Objective-J (une implémentation d’Objective-C pour JavaScript). L’univers Apple semble avoir son mot à dire concernant l’univers Internet.

L’univers de l’application web se met à ressembler, à imiter du moins, de plus en plus à celui des applications desktop, les outils et recommandations s’étoffant, comme ARIA. Le point qui m’intéresse est d’explorer à quel point on peut apprendre de ce monde là, qui est déjà codifié, qui a sû trouver des solutions aux problèmes étant les siens.

Pour ceux ayant une petite expérience avec différents toolkits graphiques, on peut voir les parallèles entre :

Sinon, en refaisant l’Observer pattern, il m’a été facile de réaliser un système dit de pub/sub organisé en canaux. On retrouve cette organisation au sein du protocole Bayeux ou dans certaines bibliothèques pour XMPP (Jabber) où les canaux sont des chemins XPath. J’aime bien ce système car il fonctionne de manière centralisée, connaître qui émet quand on est un récepteur ne nous intéresse pas, ne n’est même pas accessible. Il n’y a pas d’avantage ou de désavantage clair sur un mode utilisant le pattern observateur si ce n’est qu’il ne faille pas se marcher dessus avec les canaux utilisés.

Et pour revenir à Sproutcore, Objective-J, Objective-C, Cocoa; ils contiennent une idée intéressante nommée Key Value Observer (KVO). Le principe est d’observer les modifications des objets directement et d’éviter d’avoir à passer par un tier, qu’il soit écouteur ou observateur. Simple et efficace, même si avoir à utiliser des getters/setters ne me plait qu’à moitié, et encore, la moitié vide du verre.

Une application web à présent doit en avoir terminé avec son besoin d’être non-obtrusif, c’est une vieille rengaine devant être dépassée avec les outils actuels comme low-pro (oui il faut bien placer Prototype aussi, le pauvre). Elle doit se concentrer sur une modularité la rendant, plus simple, plus maintenable, plus testable, plus ouverte également aux mash-ups.

Je vous laisse jouer avec la page suivante, qui contient différents exemples, c’est un peu brut de fonderie; mais peut-être intéressant.

About

meYoan Blanc is a web developer that lives in Lausanne (rue Couchirard 15, 1004 Switzerland) worked for Yahoo! and comes from La Chaux-de-Fonds. This web site is for this weblog, a playground for random stuffs and can help keepingmeconnected with some friends out there.

Get my vCard or contact me by phone (+41 21 625 82 09) or email ().

Misc

RSS, list.blogug.ch

This site reflects only my opinion and is not affiliated with anyone else.

copyright 2006-2008 — doSimple.ch