Saturday, December 14, 2013

Designing of Large Scale JavaScript Application Part 4

In the previous article we have seen that Modular approach is best suite for a big application. Designing of modules are crucial part for large scale application but one thing that is pending is How different modules can inteact with each other. The important point we suggest is to make the modules less dependent, loosly coupled, etc etc. butHow?


In realistic scenarios we have seen that majority of modules are dependent on each other. Like if user performs an action on one module the other modlues should be updated simultaneously e.g: if we comment on a post shared by our friend on FaceBook not only the common module notified but also post module also gets the notification to update the number of comments on it, notification module is also notified to say "XXX user post a comment on YYY's post" and same for other modules. How other modules are notified about the activity as we have designed the application with lots of loosely coupled modules? and we keep most of the information private with in a module.

For interaction between the modules there are some mechanism knowingly or unkonwingly we generally talk about them:
  • Publisher - Subscriber 
  • Observable 
  • Mediator
  • Event Driven Framwork
  • Notification Loops
  • Event Delegation ..... etc.
The core concept of interest behind these terms is to implement interactions between loosely coupled modules. 
A mediator encapsulates how disparate modules interact with each other by acting as an intermediary.
Consider a mediator is a module that invokes the method on different modules that are interested in listening to this specific event. 

Think a mediator is an mail chord that triggers appropriate methods on the different appropriate modules (modules that are interested). 

Suppose you are playing "Shoot the target" game.Think when you fire a bullet and it hits the target what would happen according to modular implementation.
  • The target board module raises an event say "target:BulletHit"
Now if there is not mechanism for interaction the the game will ends up here thats it. But if we implemented a proper mechanism for coordination between different modules then its duty of Mediator to invoke some methods to the appropriate modules as
  • It invokes sound manager to paly some sound clip for bullet and target colission (sound manager module should be listening to  "target:BulletHit" event).
  • It invokes animation manager to animate some effects for bullet and target colission (animation manager module should be listening to  "target:BulletHit" event).
  • It invokes application manager to to validate state of of other modules like Is playing time is over. and fire different events to make the game interavtive
Look below at the sample implementation of the Mediator
In the code snippet of Mediator you have seen that there is a  parameter : channel which plays an important role. Well a channel is a unique key or name designated to an event which is used in the two way communication between publisher and subscriber like "target:BulletHit". So, a Subscriber  will subscribe to this channel - so with initiatialization, subscriber will say "yes i am interested to listen any event with channel" and Publisher will publish an event and pass the necessary information using this channel. So, publisher will say "I am in state to publish this event along with data in parameters".
var mediator = (function(){
    var subscribe = function(channel, fn){
        if (!mediator.channels[channel]) mediator.channels[channel] = [];
        mediator.channels[channel].push({ context: this, callback: fn });
        return this;
    },
    publish = function(channel){
        if (!mediator.channels[channel]) return false;
        var args = Array.prototype.slice.call(arguments, 1);
        for (var i = 0, l = mediator.channels[channel].length; i < l; i++) {
            var subscription = mediator.channels[channel][i];
            subscription.callback.apply(subscription.context, args);
        }
        return this;
    };
    return {
        channels: {},
        publish: publish,
        subscribe: subscribe,
        installTo: function(obj){
            obj.subscribe = subscribe;
            obj.publish = publish;
        }
    };
}());
Now with this approach our main concern is also get resolved. i.e. interdependency of one module over other.
In the above sample scenario of game. suppose sound manager gets crashed or unable to play the sound, the animation manager and application manager has its no impact on their working. The other modules are self sufficient and intelligent enough to perform their task. So. user will not hear the sound but can be able to play the rest of the game.

0 comments:

Post a Comment