Vishful thinking…

Writing better javascript – Part 5

Posted in javascript by viswaug on November 19, 2008

Use the module pattern to better organize your code.

Good JavaScript programming practices will help you debug and diagnose problems better. It will also keep you sane when the applications grow bigger and will be more maintainable. One of the things that I tend to do these days when I see any applications developed using the ESRI JS API, Google Maps API or the VirtualEarth API is to do a “View Page Source” on the we page. It is surprising to see many of those applications have a considerable amount of application logic on the web page itself as a series of javascript functions. I have been using the JavaScript module pattern to better organize my code and I find it satisfactory for most of my requirements. Obviously, that is not the only way to organize your code but I like it because it helps me think in terms of classes with private & public properties and methods.

Creating a class using the module pattern is pretty simple. The snippet below illustrates how to create a new class. It is only an illustration of the technique and doesn’t mean much.

var MapManager = function(/*constructor arguments defined here*/) {

    //Declare private variables here
    var _mapElement;

    //Declare private methods here
    var _addLayer = function(layer) {
        //private properties and methods CAN be accessed here
        //public properties and methods CANNOT be accessed here

        //add the layer here
    };

    return {

        //Declare public properties here
        element: _mapElement,
        data: new Object(),

        //Declare public methods here
        addLayer: function(layer) {
            //private properties and methods CAN be accessed here
            _addLayer(layer);
        }
    };
};

The class ‘MapManager’ defined above defines its private and public memebers. When an instance of the ‘MapManager’ class is created the instance returned can only be used to access and change its public properties and methods and not its private members.  The ‘new’ keyword can be used to create an instance of the ‘MapManger’ class like below.

var instance = new MapManager();

Just for a little insight into the technique, when you create an instance of the class, the object that is defined as a JSON literal after the ‘return’ keyword is the object that gets returned. And this returned object still has access to the private members in the class definition above because of the concept of closures in JavaScript.

This technique should be satisfactory for most simple design needs but most JavaScript frameworks offer their own technique to create classes, inherit from them and other advanced OO concepts. I hope to post at a later time on inheritance when using the module pattern.

About these ads

7 Responses

Subscribe to comments with RSS.

  1. Morten said, on November 19, 2008 at 7:10 pm

    I would suggest using the prototype pattern instead. With your approach a new instance of the addLayer function is created on each instance, but if you are declaring it on a prototype instead, it will only be stored in memory once:

    MapManager = function(mapElement) {
    this._element = mapElement;
    this._data = {};
    this._layers = [];
    }
    MapManager.protytype = {
    addLayer : function(layer) {
    Array.add(this._layers, layer);
    }
    }

    var instance = new MapManager(myMap);
    instance.addLayer(myLayer);

  2. viswaug said, on November 19, 2008 at 7:20 pm

    Hi Morten,

    The module pattern is flexible enough to allow only one instance in memory also. You just have to end the function definition with ‘()’. Meaning the function gets executed already and you can’t say new anymore. It is more like a singleton pattern if you will.

    Also, if I have 2 or maps on my page, then I will more MapManagers also. So, the module pattern is more flexible that way also.

    Thank You,
    Vish

  3. Emmster said, on November 20, 2008 at 2:10 pm

    I’d recommend using namespaces as well. In cases where there could potentially be JS functions from multiple sources on one page, this prevents having functions overwriting each other.

  4. viswaug said, on November 20, 2008 at 4:01 pm

    Hi Emmster,

    Thank for you for the recommendation. I do use namespaces for better organization and to avoid conflicts. I just wanted to keep the post simple for starters.

    Vish

  5. Jayant said, on November 20, 2008 at 7:44 pm

    Although these posts are mainly about JavaScript in general, but if you are using a toolkit (for example Dojo in ArcGIS JavaScript API), it is better to follow the same object patterns in your code. For creating classes in Dojo, please see Declaring a Class. I would recommend going through the whole Object Orientation chapter of the Dojo book.

  6. viswaug said, on November 21, 2008 at 3:00 am

    Hi Jayant,

    I am aware of the Dojo OO capabilities. But it might be just preference thing that I actually like the module pattern better. I understand that creating classes style is a little more powerful and flexible. But there is also not a way to hide data from the consumers (like private members). It is good if you want to hack your way around it. Like, for eg. some of things that I think are missing in the JS API public methods or properties like a base layer property on the map, can be worked around by just accessing the map._baseLayer which is supposed to be hidden or atleast that was the developer’s intent.

    But I agree that each developer needs to make that decision based on his requirements and what he/she is comfortable with.

    Thank You,
    Vish

  7. [...] while ago I had written about using the javascript module pattern to organize code a little better. But off late, I have moved away from using the module pattern [...]


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 )

Google+ photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: