In depth understanding of the JavaScript series (36) : mediation of design patterns

  • 2020-05-10 17:39:22
  • OfStack

introduce

The mediator pattern (Mediator) encapsulates a series 1 of object interactions with a mediation object. The mediator loosens the coupling of objects by eliminating the need for explicit references to each other, and allows them to change their interactions independently.

Main content from: http: / / www addyosmani. com resources/essentialjsdesignpatterns book / # mediatorpatternjavascript

The body of the

In software development, the mediator is a behavioral design pattern that allows different parts of the system to communicate by providing a unified interface. In general, if the system has many sub-modules that need to communicate directly, a central control point should be created for each module to interact with each other through this central control point. The mediator pattern allows these submodules to decouple without direct communication.

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

Let's use pseudocode to understand 1:


// The following code is pseudo-code, please do not care too much about the code
// Here, app Namespaces act as mediators
var app = app || {};
 
// through app The mediator does it Ajax request
app.sendRequest = function ( options ) {
    return $.ajax($.extend({}, options);
}
 
// request URL Later, show View
app.populateView = function( url, view ){
  $.when(app.sendRequest({url: url, method: 'GET'})
     .then(function(){
         // According to the content
     });
}
 
// Empty content
app.resetView = function( view ){
   view.html('');
}

In JavaScript, mediator is very common, which is equivalent to the message Bus on the observer mode. However, instead of calling pub/sub as the observer does, it is managed through the mediator system 1. Let's give an example based on the observer:

var mediator = (function () {
    // To subscribe to 1 Event, and provide 1 The callback function after the event is triggered
    var subscribe = function (channel, fn) {
        if (!mediator.channels[channel]) mediator.channels[channel] = [];
        mediator.channels[channel].push({ context: this, callback: fn });
        return this;
    },     // Broadcast events
    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;
        }
    }; } ());

The calling code is relatively simple:

(function (Mediator) {     function initialize() {         // The default value
        mediator.name = "dudu";         // To subscribe to 1 An event nameChange
        // The callback function shows the information before and after the modification
        mediator.subscribe('nameChange', function (arg) {
            console.log(this.name);
            this.name = arg;
            console.log(this.name);
        });
    }     function updateName() {
        // The broadcast triggers an event with the new data as the parameter
        mediator.publish('nameChange', 'tom'); // dudu, tom
    }     initialize(); // Initialize the
    updateName(); // call })(mediator);

The mediator and the observer

Now, you might be confused, the mediator and the observer seem to be the same, what's the difference? It's kind of similar, but let's look at the details:

The observer pattern, no packaging constraints of a single object, on the contrary, the observer Observer and concrete class Subject is 1 up cooperate to maintain the constraint, communication is through multiple observer and a concrete class interaction: each concrete class usually contain more than one observer, and sometimes one observer in the concrete class is also another one observer of the concrete class.

What the mediator pattern does is not simply distribute, but act as a custodian of these constraints.

Intermediaries and appearance patterns

Many people may also be confused by the difference between intermediaries and appearance patterns, which are abstractions of existing modules, but with some subtle differences.

What the mediator does is communicate between modules, which is multi-directional, but the facade pattern simply defines a simple interface for a particular module or system without adding additional functionality. Other modules in the system are not directly related to the concept of appearance pattern and can be considered as unidirectional.


Give another complete example:


<!doctype html>
<html lang="en">
<head>
    <title>JavaScript Patterns</title>
    <meta charset="utf-8">
</head>
<body>
<div id="results"></div>
    <script>
        function Player(name) {
            this.points = 0;
            this.name = name;
        }
        Player.prototype.play = function () {
            this.points += 1;
            mediator.played();
        };
        var scoreboard = {             // The container that displays the content
            element: document.getElementById('results'),             // Update score display
            update: function (score) {
                var i, msg = '';
                for (i in score) {
                    if (score.hasOwnProperty(i)) {
                        msg += '<p><strong>' + i + '<\/strong>: ';
                        msg += score[i];
                        msg += '<\/p>';
                    }
                }
                this.element.innerHTML = msg;
            }
        };         var mediator = {             // All of the player
            players: {},             // Initialize the
            setup: function () {
                var players = this.players;
                players.home = new Player('Home');
                players.guest = new Player('Guest');
            },             // play Later, update the score
            played: function () {
                var players = this.players,
                    score = {
                        Home: players.home.points,
                        Guest: players.guest.points
                    };                 scoreboard.update(score);
            },             // Handle user keystroke interactions
            keypress: function (e) {
                e = e || window.event; // IE
                if (e.which === 49) { // The number keys "1"
                    mediator.players.home.play();
                    return;
                }
                if (e.which === 48) { // The number keys "0"
                    mediator.players.guest.play();
                    return;
                }
            }
        };         // go!
        mediator.setup();
        window.onkeypress = mediator.keypress;         // 30 End in seconds
        setTimeout(function () {
            window.onkeypress = null;
            console.log('Game over!');
        }, 30000);
    </script>
</body>
</html>

conclusion

Mediator model as applied to 1 set of objects has been well defined but in complex ways to communicate, 1 case, mediator pattern is easy to use in the system, but also easy to misuse in the system, when the system appeared a many-to-many interaction complex object group, don't rush to use broker mode, but l think about whether there is something wrong with the system design.

In addition, because the mediator pattern turns the interaction complexity into the complexity of the mediator itself, the mediator object is more complex than any other object.


Related articles: