This is the 11th day of my participation in the August More Text Challenge

The role of the mediator pattern is to decouple objects from each other. By adding a mediator object, all related objects communicate through the mediator object rather than referring to each other, so when an object changes, the mediator object only needs to be notified.

A real intermediary

1. Airport commander

A mediator is also called a mediator. In reality, each aircraft only needs to communicate with the control tower. As a mediator, the control tower knows the flight status of each plane, so it can arrange the takeoff and landing times of all planes and make timely course adjustments.

2 Gambling Company

During the World Cup to buy football lottery tickets, gambling companies as an intermediary, everyone only need to be associated with gambling companies, gambling companies will calculate good odds according to the betting situation of all people, lottery people won money from the gambling company to take, lost money to the gambling company.

An example of the broker pattern — buying goods

Requirements: The page for purchasing mobile phones can be realized. In the purchase process, you can choose the color of mobile phones and input the purchase quantity. At the same time, there are two display areas in the page to show users the color and quantity just selected. There is also a button to dynamically display the next operation. We need to query the inventory corresponding to the mobile phone of this color. If the inventory quantity is less than the purchase quantity this time, the button will be disabled and show that the inventory is insufficient; otherwise, the button can be clicked and show that the mobile phone is put into the shopping cart.

Assume that the mobile phone inventory is:

var goods = {
  "red": 3."blue": 6
}
Copy the code

Then the page will have the following scenarios:

  1. Choose the red phone, buy 4, stock is low.
  2. Choose blue phones, buy 5, stock enough to add to cart.
  3. When no purchase quantity is entered, the button is disabled and a prompt is displayed.

So basically there are at least five nodes:

  • Drop down selection boxcolorSelect
  • Text entry fieldnumberInput
  • Display color informationcolorInfo
  • Display purchase quantity informationnumberInfo
  • The button that decides what to do nextnextBtn

Start coding

HTML code:

Select color:<select id="colorSelect">
  <option value="">Please select a</option>
  <option value="red">red</option>
  <option value="blue">blue</option>
</select>Input purchase quantity:<input type="text" id="numberInput" />You have selected the color:<div id="colorInfo"></div>You entered the quantity:<div id="numberInfo"></div>
<button id="nextBtn" disabled="true">Please select phone color and purchase quantity</button>
Copy the code

We then listen for the onchange event function of colorSelect and the onInput event function of numberInput, respectively, and handle them accordingly.

var colorSelect = document.getElementById('colorSelect'),
  numberInput = document.getElementById('numberInput'),
  colorInfo = document.getElementById('colorInfo'),
  numberInfo = document.getElementById('numberInfo'),
  nextBtn = document.getElementById('nextBtn');

var goods = { // Mobile phone inventory
  "red": 3."blue": 6
};
colorSelect.onchange = function () {
  var color = this.value, / / color
    number = numberInput.value,
    stock = goods[color]; // The current inventory of this color of mobile phone
  colorInfo.innerHTML = color;
  if(! color) { nextBtn.disabled =true;
    nextBtn.innerHTML = 'Please select phone color';
    return;
  }
  if (((number - 0) | 0) !== number - 0) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Please enter the correct purchase quantity';
    return;
  }
  // Whether the purchase quantity entered by the user is a positive integer
  if (number > stock) { // The current number of selections does not exceed the inventory
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Understock';
    return;
  }
  nextBtn.disabled = false;
  nextBtn.innerHTML = 'Add to cart';
};
Copy the code

Relationships between objects

Consider what happens when the onchange of colorSelect is triggered. First of all, we need to make the currently selected color display in colorInfo, and then obtain the purchase quantity currently entered by the user to judge the validity of the user’s input value. The display status of nextBtn is judged according to the number of inventory.

numberInput.oninput = function () {
  var color = colorSelect.value, / / color
    number = this.value, / / the number of
    stock = goods[color]; // The current inventory of this color of mobile phone
  numberInfo.innerHTML = number;
  if(! color) { nextBtn.disabled =true;
    nextBtn.innerHTML = 'Please select phone color';
    return;
  }
  if (((number - 0) | 0) !== number - 0) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Please enter the correct purchase quantity';
    return;
  }
  if (number > stock) { // The current number of selections does not exceed the inventory
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Understock';
    return;
  }
  nextBtn.disabled = false;
  nextBtn.innerHTML = 'Add to cart';
};
Copy the code

Possible difficulties

While the code is now complete, the requirements changes that come with it can cause problems for us. Suppose we now want to remove colorInfo and numberInfo from the display fields, we need to change the code in colorSelect.onchange and numberInput.onput, because in the previous code, these objects were indeed coupled together.

So now we need to add another drop-down box to the page to select the phone memory, and we need to calculate the color, memory and purchase quantity to determine whether nextBtn is out of stock or in the cart.

Start by adding two HTML nodes:

Select memory:<select id="memorySelect">
  <option value="">Please select a</option>
  <option value="32G">32G</option>
  <option value="16G">16G</option>
</select>You chose memory:<div id="memoryInfo"></div>
<script>
memorySelect = document.getElementById('memorySelect'),
memoryInfo = document.getElementById('memoryInfo')
</script>
Copy the code

Next modify the JSON object representing the repository and modify the onchange event function of colorSelect:

var goods = { // Mobile phone inventory
  "red|32G": 3.// Red 32G, stock 3
  "red|16G": 0."blue|32G": 1."blue|16G": 6
};
colorSelect.onchange = function () {
/// In addition to the above code, there are the following judgments
  var color = this.value, / / color
    number = numberInput.value,
    stock = goods[color + '|' + memory]; // The current inventory of this color of mobile phone

  if(! memory) { nextBtn.disabled =true;
    nextBtn.innerHTML = 'Please select memory size';
    return; }}Copy the code

Also change some code for numberInput events.

Finally, add the onchange event function of memorySelect:

memorySelect.onchange = function () {
  var color = colorSelect.value,
    number = numberInput.value,
    memory = this.value,
    stock = goods[color + '|' + memory];
  if(! color) { nextBtn.disabled =true;
    nextBtn.innerHTML = 'Please select phone color';
    return;
  }
  if(! memory) { nextBtn.disabled =true;
    nextBtn.innerHTML = 'Please select memory size';
    return;
  }
  if (((number - 0) | 0) !== number - 0) {
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Please enter the correct purchase quantity';
    return;
  }
  if (number > stock) { // The current number of selections does not exceed the inventory
    nextBtn.disabled = true;
    nextBtn.innerHTML = 'Understock';
    return;
  }
  nextBtn.disabled = false;
  nextBtn.innerHTML = 'Add to cart';
}
Copy the code

As you can see, adding just one memory selection condition requires so much code modification because in the current implementation, each node object is coupled together, and any change or addition of a node object is notified to its associated object.

Bring in intermediaries

Now we introduce the mediator object, where all node objects talk only to the mediator. When event behavior occurs in the dropdown selection boxes colorSelect, memorySelect, and text input box numberInput, they simply inform the mediator that they have been changed and pass themselves in as parameters so that the mediator can identify who has changed. Everything else is left to the intermediary object.

var goods = { // Mobile phone inventory
  "red|32G": 3."red|16G": 0."blue|32G": 1."blue|16G": 6
};
var mediator = (function () {
  var colorSelect = document.getElementById('colorSelect'),
    memorySelect = document.getElementById('memorySelect'),
    numberInput = document.getElementById('numberInput'),
    colorInfo = document.getElementById('colorInfo'),
    memoryInfo = document.getElementById('memoryInfo'),
    numberInfo = document.getElementById('numberInfo'),
    nextBtn = document.getElementById('nextBtn');
  return {
    changed: function (obj) {
      var color = colorSelect.value, / / color
        memory = memorySelect.value,/ / memory
        number = numberInput.value, / / the number of
        stock = goods[color + '|' + memory];  // The color and memory correspond to the number of phones in stock
      if (obj === colorSelect) { // If the change is to select the color dropdown box
        colorInfo.innerHTML = color;
      } else if (obj === memorySelect) {
        memoryInfo.innerHTML = memory;
      } else if (obj === numberInput) {
        numberInfo.innerHTML = number;
      }
      if(! color) { nextBtn.disabled =true;
        nextBtn.innerHTML = 'Please select phone color';
        return;
      }
      if(! memory) { nextBtn.disabled =true;
        nextBtn.innerHTML = 'Please select memory size';
        return;
      }
      if (((number - 0) | 0) !== number - 0) {
        nextBtn.disabled = true;
        nextBtn.innerHTML = 'Please enter the correct purchase quantity';
        return;
      }
      nextBtn.disabled = false;
      nextBtn.innerHTML = 'Add to cart'; }}}) ();// event function:
colorSelect.onchange = function () {
  mediator.changed(this);
};
memorySelect.onchange = function () {
  mediator.changed(this);
};
numberInput.oninput = function () {
  mediator.changed(this);
};
Copy the code

It is possible to imagine that one day we would need to add some more nodes that are related to the requirements, such as the CPU model, and we would just need to change the Mediator object slightly:

var goods = { // Mobile phone inventory
  "red|32G|800": 3.// The color is red, the memory is 32GB, and the number of cpus is 3
  "red|16G|801": 0."blue|32G|800": 1."blue|16G|801": 6
};
var mediator = (function () {
  var cpuSelect = document.getElementById('cpuSelect');
  return {
    change: function (obj) {
      / / a little
      var cpu = cpuSelect.value,
        stock = goods[color + '|' + memory + '|'+ cpu]; }}/ / a little
  if (obj === cpuSelect) {
    cpuInfo.innerHTML = cpu;
  }
})();
Copy the code

Advantages and disadvantages of the mediator model

The mediator pattern decouples objects, replacing the mesh many-to-many relationship between objects with a one-to-many relationship between the mediator and objects. Each object only needs to pay attention to the realization of its own function, and the interaction between objects is handed over to the intermediary object to realize and maintain.

However, there are some drawbacks to the mediator model. One of the biggest disadvantages is the addition of a mediator object to the system, because the complexity of the interaction between objects is transferred to the complexity of the mediator object, making the mediator object often huge. The mediator object itself is often a difficult object to maintain.

One last word

If this article is helpful to you, or inspired by the words, help like attention, your support is the biggest motivation I insist on writing, thank you for your support.

Same series of articles

  1. A singleton of JavaScript design patterns
  2. JavaScript design pattern strategy pattern
  3. JavaScript design pattern proxy pattern
  4. Iterator pattern for JavaScript design pattern
  5. Publish – subscribe JavaScript design pattern
  6. JavaScript design mode command mode
  7. A combination of JavaScript design patterns
  8. JavaScript design pattern template method pattern
  9. Meta-patterns for JavaScript design patterns
  10. The JavaScript design pattern’s chain of responsibility pattern
  11. The JavaScript design pattern mediator pattern
  12. Decorator pattern for JavaScript design pattern
  13. JavaScript design pattern state pattern
  14. Adapter pattern for JavaScript design pattern