SoFunction
Updated on 2025-03-09

A deep understanding of JavaScript series (36): Detailed explanation of the intermediary model of design patterns

introduce

Mediator mode (Mediator) uses a mediator object to encapsulate a series of object interactions. The intermediary makes the objects need not be explicitly referenced to each other, thereby loosely coupling them and can independently change their interactions.

Main content comes from:/resources/essentialjsdesignpatterns/book/#mediatorpatternjavascript

text

In software development, intermediaries are a behavioral design pattern that allows different parts of the system to communicate by providing a unified interface. Generally, if the system has many submodules that need to be communicated directly, a central control point must be created for each module to interact through the central control point. The intermediary model allows these submodules to achieve the purpose of decoupling without direct communication.

For example, the common airport traffic control system, the tower is an intermediary, which controls the takeoff and landing of the aircraft (submodule), because all communication is completed from the aircraft reporting to the tower, rather than communicating with each other before the aircraft. The central control system is the key to the system, that is, the role of intermediary in software design.

Let's first understand it using pseudo-code:

Copy the codeThe code is as follows:

// The following code is pseudo-code, please don't pay too much attention to the code
// Here the app namespace is equivalent to playing the role of an intermediary
var app = app || {};
 
// Make Ajax requests through app intermediary
= function ( options ) {
    return $.ajax($.extend({}, options);
}
 
// After requesting the URL, display the View
= function( url, view ){
  $.when(({url: url, method: 'GET'})
     .then(function(){
//Show content
     });
}
 
// Clear content
= function( view ){
   ('');
}

In JavaScript, intermediaries are very common, equivalent to message Bus in the observer pattern. However, they are not implemented by calling pub/sub like observers, but are managed by intermediaries in a unified manner. Let us give an example based on the observer:
Copy the codeThe code is as follows:

var mediator = (function () {
// Subscribe to an event and provide a callback function after the event is triggered
    var subscribe = function (channel, fn) {
        if (![channel]) [channel] = [];
        [channel].push({ context: this, callback: fn });
        return this;
    },

// Broadcast events
    publish = function (channel) {
        if (![channel]) return false;
        var args = (arguments, 1);
        for (var i = 0, l = [channel].length; i < l; i++) {
            var subscription = [channel][i];
            (, args);
        }
        return this;
    };

    return {
        channels: {},
        publish: publish,
        subscribe: subscribe,
        installTo: function (obj) {
            = subscribe;
            = publish;
        }
    };

} ());


Calling the code is relatively simple:
Copy the codeThe code is as follows:

(function (Mediator) {

    function initialize() {

// default value
        = "dudu";

// Subscribe to an event name change
// The callback function displays information before and after modification
        ('nameChange', function (arg) {
            ();
            = arg;
            ();
        });
    }

    function updateName() {
// Broadcast trigger event, parameter is new data
        ('nameChange', 'tom'); // dudu, tom
    }

initialize(); // Initialization
updateName(); // Call

})(mediator);


Intermediaries and observers

At this point, everyone may be confused. The intermediary and the observer seem to be similar. What is the difference? It's actually a bit similar, but let's take a look at the specific description:

Observer pattern, a single object that does not encapsulate constraints. On the contrary, observer Observer and concrete class Subject work together to maintain constraints. Communication interacts through multiple observers and multiple concrete classes: each concrete class usually contains multiple observers, and sometimes one observer in the concrete class is also the concrete class of another observer.

What the intermediary model does is not simply distribution, but it plays the role of maintaining these constraints.

Intermediary and Appearance Patterns

Many people may also be confused about the difference between intermediary and appearance patterns. They both abstract the existing modules, but there are some subtle differences.

What the intermediary does is to communicate between modules, which is multidirectional, but the appearance mode simply defines a simple interface for a certain module or system without adding additional functionality. The concept of other modules in the system has no direct connection with the appearance mode and can be considered one-way.


Here is another complete example:

Copy the codeThe code is as follows:

<!doctype html>
<html lang="en">
<head>
    <title>JavaScript Patterns</title>
    <meta charset="utf-8">
</head>
<body>
<div ></div>
    <script>
        function Player(name) {
            = 0;
            = name;
        }
        = function () {
            += 1;
            ();
        };
        var scoreboard = {

// Container to display content
            element: ('results'),

// Update score display
            update: function (score) {
                var i, msg = '';
                for (i in score) {
                    if ((i)) {
                        msg += '<p><strong>' + i + '<\/strong>: ';
                        msg += score[i];
                        msg += '<\/p>';
                    }
                }
                = msg;
            }
        };

        var mediator = {

// All players
            players: {},

// Initialization
            setup: function () {
                var players = ;
                = new Player('Home');
                = new Player('Guest');
            },

// After play, update the score
            played: function () {
                var players = ,
                    score = {
                        Home: ,
                        Guest:
                    };

                (score);
            },

// Handle user key interaction
            keypress: function (e) {
                e = e || ; // IE
if ( === 49) { // Number key "1"
                    ();
                    return;
                }
if ( === 48) { // Number keys "0"
                    ();
                    return;
                }
            }
        };

        // go!
        ();
        = ;

// End after 30 seconds
        setTimeout(function () {
            = null;
            ('Game over!');
        }, 30000);
    </script>
</body>
</html>

Summarize

The intermediary mode is generally used in situations where a group of objects has been well defined but communicates in a complex way. Generally speaking, the intermediary mode is easy to use in the system, but it is also easy to misuse in the system. When a complex object group of many-to-many interactions appears in the system, don’t rush to use the intermediary mode first, but think about whether there is something wrong with the system design.

In addition, since the intermediary model turns interaction complexity into the complexity of the intermediary itself, the intermediary object will be more complex than any other object.