dimanche 3 avril 2016

Mediator Pattern vs. Direct Calls to Intermediate Function

How is the Mediator design pattern, e.g. something like this:

var mediator = (function(){

var _jobs = {};


function _extractedParams(arguments){
    var arr = [];
    if (arguments.length > 1){
        for (var i=1; i < arguments.length; i++) arr.push(arguments[i]);
    } 
    return arr;
}


function _defaultSubscribeCallback(){
    console.log("_defaultSubscribeCallback()");
}


return {

    subscribe: function(){
        var channel = arguments[0];

        if (!_jobs.hasOwnProperty(channel)) _jobs[channel] = [];

        _jobs[channel].push({
            originalParams: _extractedParams(arguments),
            callback: arguments[1] || _defaultSubscribeCallback
        });

    },

    publish: function(){
        var channel = arguments[0];

        if (!_jobs.hasOwnProperty(channel)) return 0;

        for (var i=0; i < _jobs[channel].length; i++){
            var subscription = _jobs[channel][i];

            subscription.callback.apply(this, subscription.originalParams);
        }

        return 1;  
    }

};

}());

var module1 = (function(){

    return {
        myFunction: function(){
           console.log(arguments[0]); //"Hello"
        }
    };

}());

mediator.subscribe("LOG_IN", module1.myFunction, "Hello");

var module2 = (function(){

    mediator.publish("LOG_IN");

}());

...better than simply calling an intermediate function when one module wants to communicate with another, e.g. something like this?:

var mediator = (function(){

    return {
        runFunction: function(){
            var params;

            if (arguments.length > 1){
                params = [];
                for (var i=1; i < arguments.length; i++) params.push(arguments[i]);
            }

            if (arguments[0] && typeof arguments[0] === "function") arguments[0](params);
        }
    };

}());

var module1 = (function(){

    return {
        myFunction: function(){
           console.log(arguments[0]); //"Hello"
        }
    };

}());

var module2 = (function(){

    mediator.runFunction(module1.myFunction, "Hello");

}());

While both strategies seem to have the same benefits (decoupling, etc.), the first example produces overhead by holding onto the subscriptions in _jobs (though I didn't include it, I would supply an unsubscribe() method to help mitigate this, but it would remain an issue); is far more complicated than the second example; will cause a slight dip in performance; and is more likely to encounter problems.

What am I not understanding about the Mediator pattern? Why does it seem like an unnecessarily convoluted way of achieving a simple result? Why would I want all those subscriptions floating around in _jobs?

Aucun commentaire:

Enregistrer un commentaire