Coding tips: accessing the data structure

I think it is really important keep the code more general and flexible as possible; one rule, that i would like to introduce here, is to use the right level of abstraction when accessing the data structure elements, trying to centralize the read / write operations on them.

Many times i saw pieces of code that work directly on the data structure: that is a problem when that data structure, at some point, gets changed and then the developers are forced to manually update every line of code involved with it.

A real example: let think about implementing a piece code that meets this requirement:

Using jQuery and a table as target, clicking on a td of the table, we want to get it selected. When a td is selected, the click makes it deselected. The var tableSelector will be the selector to get the target table. Also, we want the selected elements stored into a list.

This is an implemention i don’t like:

// global (for the click's handler) selection
// and selectedClass vars
var selection = [],
    selectedClass = "selected";

$(tableSelector).click( function(e) {
    // i am not sure about nodeName as the best choice
    if( e.target.nodeName == "TD" ) {
        var i = 0,
            el = e.target;

        // when an index of selection refers to el,
        // the condition (i < selection.length ) is true
        for(; selection[i] != el; i++) {};

        // selected state toggle
        if( i < selection.length ) {

    	    selection.push( el );
    	    el.addClass( selectedClass );

        } else {

            selection.splice(i, 1);
            el.removeClass( selectedClass );

        }
    }
});

Checking this code, the selection array is directly accessed: every where you use the selection, you assume it is an array (note: the real bad here is that the event handler has got some application logic, by accessing the data structure, but it helps the example so i don’t go through this point).
What to do if, at some point, you need to make an hash map of it? You will get to check every line of code involved with it and changing them, like that:

// global (for the click's handler) selection
// and selectedClass vars
var selection = {},
    selectedClass = "selected";

$(tableSelector).click( function(e) {
    // i am not sure about nodeName as the best choice
    if( e.target.nodeName == "TD"; ) {
        var i,
            el = e.target,
            isSelected = false;

        for( i in selection[i] ) {
            if( i == el ) {
                isSelected = true;
                break;
            }
        }
        
        // selected state toggle
        // i am assuming that el 
        // has got an id but it is
        // not obvious
        if( !isSelected ) {

    	    selection[ el.id ] = el;
    	    el.addClass( selectedClass );

        } else {

            delete selection[ el.id ];
            el.removeClass( selectedClass );

        }
    }
});

In the example there are only few lines to be changed but, in a real work enviroment, probably lines will be many and in different places.
How to avoid this situation? What i like to do is to centralize the data structure access, like that:

// you would like to add COMMENTS for the
// class, contructor and every member!
var Selection = function() {
    this._selection = [];
}
Selection.prototype.select = function(el) {
    if( !this.has(el) ) {
        this._selection.push( el );
        return true;
    }
};
Selection.prototype.deselect = function(el) {
    if( this.has(el) ) {
        this._selection.splice(i, 1);
    }
};
Selection.prototype.has = function( el ) {
    // you would like to add conditions
    // to check that el is a DOM element
    if( !el ) {
        return;
    }
    var i = 0;
    for(; this._selection[i] != el; i++) {};
    return i < this._selection.length;
};
Selection.prototype.length = function () {
    return this._selection.length;
}

Now our click handler appears like this:

// global (for the click's handler) selection
// and selectedClass vars
var selection = new Selection(),
    selectedClass = "selected";

$(tableSelector).click( function(e) {
    var el = e.target;

    if( selection.toggle(el) ){
        el.addClass( selectedClass );
    } else {
        el.removeClass( selectedClass );
    }
});

We have delegated the access, to the data structure, to the Selection object: by piloting that object, we can write (and read) the data.
More, add changes to the data structure doesn’t involve the code in which we are using the selection.

I hope that can be helpful, thanks for reading!

This entry was posted in Javascript, jQuery, Programming, Tips and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s