简体   繁体   中英

Mediator Pattern vs. Direct Calls to Intermediate Function

How is the Mediator design pattern, eg 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(){

    return {

        afterAuth: function(){
           mediator.publish("LOG_IN");
        }

    };

}());

//After user authentication
module2.afterAuth();

...better than simply calling an intermediate function when one module wants to communicate with another, eg 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(){

    return {

        afterAuth: function(){
           mediator.runFunction(module1.myFunction, "Hello");
        }

    };

}());

//After user authentication
module2.afterAuth();

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 ?

I realize now that the important difference between the first and second examples is that in the second, module2 references module1 via mediator.runFunction(module1.myFunction, "Hello"); , while in the first example, module2 does not reference module1 , instead referencing only the mediator via mediator.publish("LOG_IN"); Clearly, the second example, as pointed out by @user943702, "serves no purpose."

The first approach is actually an example of Observer Pattern , in which publisher publish and subscribers listen, whereas in Mediator Pattern all modules communicate with each other through a mediator. Both patterns share the same benefit ie Decoupling. In the second approach module1 is communicating with module2 and is not decoupled (module1 is directly referring to module2) and it seems to be a perfect fit for applying Mediator Pattern if in future you are going to do lots of changes in modules and their interfaces. Better not let modules worry about the interface, let mediator do it. Separation of concerns :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM