Thursday, December 20, 2012

Occamsrazor.js 2.0 API ehnancement

I released version 2.0 of occamsrazor.js. My goal is to further simplify the API. This example is taken from my last post:

//mediator

var pubsub = occamsrazor();

// from now a validator is a simple function
var is_archive = function (obj){
    return 'getNumbers' in obj;
};

// the archive object

var archive = (function (){
    var numbers = [];
    return {
        getNumbers: function (){
            return numbers;
        },
        addItem: function (number){
            numbers.push(number);
            // this notify the event to the mediator
            pubsub.publish('changed', this);
        }
    };
}());

// the printsum isn't changed

var printsum = (function (){
    return {
        print: function (n){
            console.log(n);
        },
        sum_and_print: function (archive){
            var i,sum = 0;
            for(i = 0;i < archive.length; i++){
                sum += archive[i];
            }
            this.print(sum);
        }
    };
}());

// subscribe the event
// subscribe is an alias of "add" and "on"

// the list of validators now is before the function
pubsub.subscribe(["changed",is_archive], function (evt, archive){
    printsum.sum_and_print(archive.getNumbers());
});

//you can use a single string instead of a function as a validator

Thursday, December 6, 2012

Mediator pattern with occamsrazor.js

The mediator design pattern can be very useful to decouple a group of objects. Let's see how.

Let's say we have two very simple objects. The first is an archive of numbers:

var archive = (function (){
    var numbers = [];
    return {
        getNumbers: function (){
            return archive;
        },
        addItem: function (number){
            archive.push(number);
        }
    };
}());

The second object prints the sum of the numbers of the previous object:

var printsum = (function (){
    return {
        print: function (n){
            console.log(n);
        },
        sum_and_print: function (archive){
            var i,sum = 0;
            for(i = 0;i < archive.length; i++){
                sum += archive[i];
            }
            this.print(n)
        }
    };
}());

Ok. Now we need to recalculate and print the sum each time a new item is added to the archive. The first solution is straightforward:

...

        addItem: function (number){
            archive.push(number);
            // we call directly the function
            printsum.sum_and_print(archive);
        }
...

This could be a solution but It has a drawback: we bind explicity the two objects together. With many objects and direct dependencies this could be very difficult to manage. Moreover, chaging or adding other dependencies could translate in changing extensively the (already tested) code.

The mediator

The mediator is an object that mediates between other objects. Instead of calling functions directly we notify events to the mediator. The mediator calls every function that is subscribed to a certain event.
Let's rewrite the example using occamsrazor.js to build a mediator:

//mediator

var pubsub = occamsrazor();

// we need 2 validators, one for the event and the second for the object

// this validate the type of the event

var is_changed_event = occamsrazor.validator(function (evt){
    return evt === 'changed';
});


// this validate the type of the object

var is_archive = occamsrazor.validator(function (obj){
    return 'getNumbers' in obj;
});


// the archive object

var archive = (function (){
    var numbers = [];
    return {
        getNumbers: function (){
            return numbers;
        },
        addItem: function (number){
            numbers.push(number);
            // this notify the event to the mediator
            pubsub.publish('changed', this);
        }
    };
}());

// the printsum isn't changed

var printsum = (function (){
    return {
        print: function (n){
            console.log(n);
        },
        sum_and_print: function (archive){
            var i,sum = 0;
            for(i = 0;i < archive.length; i++){
                sum += archive[i];
            }
            this.print(sum);
        }
    };
}());

// subscribe the event

pubsub.subscribe(function (evt, archive){
    printsum.sum_and_print(archive.getNumbers());
}, [is_changed_event,is_archive])

Build a mediator with occamsrazor.js has another advantage: events are notified only for the objects that pass every validator.

Next challenge: try to integrate occamsrazor.js with backbone.js 
Stay tuned !

Tuesday, October 30, 2012

Enhancing Backbone.js with Occamsrazor.js

WARNING. This article is an early experiment ! This way to enhance backbone.js is much better!

In this post I want to share a little experiment I made with Backbone.js and Occamsrazor.js. But before that I want to explain briefly what Backbone.js and Occamsrazor.js are.

Backbone.js

Backbone.js is a Javascript library useful to build structured UI. It's main role is to coordinate one or more models with their visual representations (views). It also manage the data exchange with the backend. (It is designed to be used in the frontend).
The core of Backbone.js is made of three powerful types of object:
  • models
  • collections
  • views
The model is an atomic unit of data. The collection is a group of objects that share the same model. The view keeps updated the visual representation of a model or a collection. The coordination between each these object is decoupled using events (observer pattern).

The web is plenty of Backbone.js documentation. For example:

Occamsrazor.js

Occamsrazor.js is a plugin system I wrote some time ago. I wrote about that here and here.

Why use these libraries together ?

With Occamsrazor.js a collection can contain objects of different types. To say the truth, in my experiment there is only one type of model but it can behave differently based on its fields.
For example we can decide which view is more appropriate.

The results

The demo is here (it is quite funny, I put in box2d and other libraries).
The "CanvasPlayView" view is responsible to draw all of the bodies on a canvas. In the render method we found this:

        models.bodies.each(function (element, index){
            var pos, x, y, angle;
            pos = positions[element.id];
            if (! pos){
                return;
            }
            x = pos.x;
            y = pos.y;
            angle = pos.angle;

            canvasLayer.ctx.save();
            canvasLayer.ctx.translate(x * canvasLayer.scale, y * canvasLayer.scale);
            canvasLayer.ctx.rotate(angle);

            plugins.drawer(element).render(canvasLayer);

            canvasLayer.ctx.restore();

        });

"Plugin.drawer" is not a regular function. It's a plugin!
This plugin is added in the rect module (the module containing all the plugins for the rectangular bodies) :

plugins.drawer.add(function (element){
    var GenericModelView = Backbone.View.extend({
        render: function(canvasLayer){
            var m = this.model,
                scale = canvasLayer.scale,
                w = m.get('width') * scale,
                h = m.get('height') * scale;

            canvasLayer.ctx.fillStyle = m.get('color');
            canvasLayer.ctx.fillRect(
                -(w / 2),
                -(h / 2),
                w,
                h
            );

            return this;
        }
    });
    return new GenericModelView({model:element });

}, plugins.validators.isBox);

More info on how Occamsrazor.js works are here.

I consider this experiment a step in the right direction.
Soon I'll try to make further steps.

Thursday, August 9, 2012

API design in Javascript


Three months ago I released an open source js library: occamsrazor.js
I firmly believe that it is very useful. Sadly I haven't had any real feedback (excepts Simone Orsi who stated "Cool experiment!" ... Thank you ).
I think It's important to listen to the feedback, even when there is not. Often people are too kind to give a sincere feedback when your work sucks. And if they don't understand what a library is for. They simply don't use it.

I slowly understood that a real example is very important to understand how a library can be useful.
So I started to work on a little demo (I'll release it as soon as possible).

Using my own library I started to think: "wow the library is useful but the API sucks !!!"

So I rewrote the API.

These are the lessons I learned:

Remove all the feature except the fundamentals

I usually follow this design principle:
"It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove." [Antoine de Saint Exupéry]


So I decided to cut some features and voilà ! Everything starts to make sense.

Keep it simple

A good API must be easy to understand and remember: this can be obtained using short but descriptive names.
It is also important not to use an unusual calling scheme:

var x = Lib.executeFunc('foo', bar);

better:

var x = Lib.foo(bar);

Add syntactic sugar

A good API must be elegant. For this reason I borrow some nice Javascript tricks from jQuery:

  • chaining
If a method doesn't need to return a value is very useful if it returns the object itself. This pattern is called chaining. An example from jQuery:

$('p').addClass('foo').fadeOut();
  • object as function
A function in Javascript is an object. Like other objects we can freely add properties: to make an example jQuery has many methods (ajax, each, map, grep) but, at the same time, is a function returning a jQuery object.


  • signature polymorphism
Sometimes can be useful if a function acts differently when the parameters are different. If we don't pass an argument to a function that argument will be undefined. Furthermore every function has a local variable called "arguments" (an array like structure) that contains all the arguments passed to the function.

I hope this article will be useful.

The new version of occamsrazor.js is on github

Tuesday, May 15, 2012

Occamsrazor.js: A Javascript component registry


Occam's Razor
This principle is often summarized as "other things being equal, a simpler explanation is better than a more complex one."
http://en.wikipedia.org/wiki/Occam%27s_razor


I am a Plone developer. For those who do not know, Plone is a powerful CMS based on the Zope application server (written in Python).

One of the best features of this CMS is the Zope Component Architecture (ZCA). It borns as a part of the Zope 3 project but It's a quite independent set of modules. ZCA allows you to build component based application.


I really missed a Javascript implementation of the ZCA or something similar. But I haven't found anything !!! Maybe, building complex and pluggable CMS in Javascript is not yet so common (no, I'm not surprised).

ZCA in Javascript ?

So I started to think to port the ZCA in Javascript, unfortunately It's not easily portable (It's written in Python and rely on Python inheritance implementation).
Furthermore some aspects of the ZCA perplexed me. These are the dark spots of the ZCA (all in my own opinion):



  • Interfaces

Interfaces are an unusual concept for dynamic languages like Python and Javascript. For example the concept of "interface" (design-by-contract programming) doesn't fit perfectly in an environment where you can create, delete or modify any attribute of an object at run time.
Python and Javascript coding style privilege attribute checking over type checking. For this reason in the day-to-day work the main use of Zope interfaces is often to "mark" an object without enforcing a specific interface (intended as a subset of attributes/methods).

  • Interface inheritance

Inheritance is a tricky matter.
Zope interface implementation is tightly coupled with the Python inheritance implementation. While it's powerful, it is also quite complex to figure out in complex inheritance chains.
Furthermore it's quite difficult to port the library in a different environment (for example Javascript).

  • Unnecessary functions and component types

ZCA API could be simpler furthermore it uses an unusual and rich terminology (components, adapters, utilities etc.).

occamsrazor.js

I eventually decided to work around some ideas and try to improve and simplify the ZCA.
The result is Occamsrazor.js

Occamsrazor.js is a library useful to decouple a functionality from the code that provide it.

Documentation and source code is here.

I'm very curious to have some feedback ...