Let’s first understand this problem. If the requirements that our front-end development contacts are given to us by the demand side, one front-end development may deal with multiple demand sides, so it will maintain contact between multiple demand sides. Then in the program, it means keeping references to multiple objects. The larger the scale of the program, more and more objects will be, and the relationship between them will become more and more complicated. Now if there is an intermediary (if our supervisor) to connect with the needs of multiple demand sides, the demand side only needs to give all the requirements to our supervisor, and the supervisor will assign tasks to us according to our workload in turn. In this way, our front-end development does not need to contact multiple business parties, we only need to contact our supervisor (that is, the intermediary). This benefit weakens the coupling between objects.
Liezi in daily life:
The intermediary model is often encountered in our daily life. For example, when we go to a real estate agency to rent a house, the real estate agent forms an intermediary between the tenant and the landlord lessor; the tenant does not care who the house is rented, and the landlord lessor does not care about who it rents to, because there is an intermediary, so an intermediary is needed to complete the transaction.
The function of the mediator pattern is to undo the coupling relationship between objects. After adding a mediator object, all relevant objects communicate through the mediator object, rather than referring to each other. Therefore, when an object sends a change, you only need to notify the mediator object. The intermediary loosens the coupling between the individual objects and can independently change the interaction between them.
The columns for implementing intermediaries are as follows:
I don’t know if you have ever played the game Hero Kill. At the earliest, there were two people (evil and self) in the hero Killing; we first use ordinary functions to implement the following for this game:
For example, first define a function. There are three methods of this function, namely win (win), lose (lose), and die (enemies die); as long as a player dies, the game ends, and its opponent needs to be notified to win; the code needs to be written as follows:
function Hero(name) { = name; = null; } = function(){ ( + 'Won'); } = function(){ ( + 'lose'); } = function(){ (); (); } // Initialize 2 objectsvar h1 = new Hero("Zhu Yuanzhang"); var h2 = new Hero("Liu Bowen"); // Set enemies for players = h2; = h1; // Zhu Yuanzhang lost when he died(); // Output Zhu Yuanzhang lost Liu Bowen Won
Now let's add teammates to the game again
For example, now we will add teammates to the game. For example, if there are 6 players in the hero killing, then in this case there will be teammates and 3 enemies; therefore, we need to distinguish whether it is an enemy or a teammate. This field requires the color of the team. If the color of the team is the same, it is the same team, otherwise it is the enemy;
We can first define an array player to save all players. After creating players, we loop players to set teammates or enemies for each player;
var players = [];
Next, let's write the Hero function; the code is as follows:
var players = []; // Define an array to save all playersfunction Hero(name,teamColor) { = []; //Save the teammate list = []; // Save the enemy list = 'live'; // Player status = name; // Character name = teamColor; // The color of the team} = function(){ // Win ("win:" + ); }; = function(){ // Lost ("lose:" + ); }; = function(){ // All teammates are alive by default var all_dead = true; = 'dead'; // Set the player status to death for(var i = 0,ilen = ; i < ilen; i+=1) { // traversal, if there is still a teammate who has not died, the game is not over yet if([i].state !== 'dead') { all_dead = false; break; } } if(all_dead) { (); // All teammates die and the game ends // Loop Notify all players of the game failure for(var j = 0,jlen = ; j < jlen; j+=1) { [j].lose(); } // Notify all enemies of victory for(var j = 0,jlen = ; j < jlen; j+=1) { [j].win(); } } } // Define a factory class to create playersvar heroFactory = function(name,teamColor) { var newPlayer = new Hero(name,teamColor); for(var i = 0,ilen = ; i < ilen; i+=1) { // If it's a player from the same team if(players[i].teamColor === ) { // Add a list of teammates to each other players[i].(newPlayer); (players[i]); }else { // Add each other to the enemy list players[i].(newPlayer); (players[i]); } } (newPlayer); return newPlayer; }; // Red Teamvar p1 = heroFactory("aa",'red'), p2 = heroFactory("bb",'red'), p3 = heroFactory("cc",'red'), p4 = heroFactory("dd",'red'); // Blue Teamvar p5 = heroFactory("ee",'blue'), p6 = heroFactory("ff",'blue'), p7 = heroFactory("gg",'blue'), p8 = heroFactory("hh",'blue'); // All Red Team players die(); (); (); (); // lose:dd lose:aa lose:bb lose:cc // win:ee win:ff win:gg win:hh
As mentioned above: Hero function has 2 parameters, name (player name) and teamColor (team color).
First of all, we can judge whether it is a teammate or an enemy based on the team color; there are also three methods: win (win), lose (lose), and die (death); if each time a person dies, the dead teammates are all dead. If all dies, they will lose. Therefore, they need to cycle their teammates and tell each member of their teammates that they have lost. At the same time, they need to cycle through their enemies and tell their enemies that they have won. Therefore, every time a person dies, they need to cycle through to determine whether his teammates are all dead; therefore, each player and other players are tightly coupled together.
Below we can use the intermediary model to improve the above demo;
First of all, we still define the Hero constructor and Hero object prototype methods. In these prototype methods of Hero object, we are no longer responsible for the specific execution logic, but pass the operations to the mediator object, and the mediator object is responsible for doing specific things. We can name the mediator object playerDirector;
The playerDirector opens an externally exposed interface ReceiveMessage, which is responsible for receiving messages sent by the player object. When the player object sends a message, it always sends its own this as a parameter to the playerDirector so that the playerDirector can recognize that the message comes from the player object.
The code is as follows:
var players = []; // Define an array to save all playersfunction Hero(name,teamColor) { = 'live'; // Player status = name; // Character name = teamColor; // The color of the team} = function(){ // Win ("win:" + ); }; = function(){ // Lost ("lose:" + ); }; // die = function(){ = 'dead'; // Send a message to the intermediary and the player dies ('playerDead',this); } // Remove player = function(){ // Send a message to the intermediary and remove a player ('removePlayer',this); }; // Players change teams = function(color) { // Send a message to the intermediary and the player changes team ('changeTeam',this,color); }; // Define a factory class to create playersvar heroFactory = function(name,teamColor) { // Create a new player object var newHero = new Hero(name,teamColor); // Send messages to intermediaries and add new players ('addPlayer',newHero); return newHero; }; var playerDirector = (function(){ var players = {}, // Save all players operations = {}; // Actions that an intermediary can perform // Add a new player operation = function(player) { // Get the color of the player teammates var teamColor = ; // If the player of this color does not have a team, a new team will be established players[teamColor] = players[teamColor] || []; // Add players to the team players[teamColor].push(player); }; // Remove a player = function(player){ // Get the color of the team var teamColor = , // Get all members of the team teamPlayers = players[teamColor] || []; //Travel for(var i = - 1; i>=0; i--) { if(teamPlayers[i] === player) { (i,1); } } }; // Players change teams = function(player,newTeamColor){ // First delete from the original team (player); // Then change the color of the team = newTeamColor; // Add to the team (player); }; // Player dies = function(player) { var teamColor = , // The team where the player is located teamPlayers = players[teamColor]; var all_dead = true; //Travel for(var i = 0,player; player = teamPlayers[i++]; ) { if( !== 'dead') { all_dead = false; break; } } // If all_dead is true, it means that all deaths are if(all_dead) { for(var i = 0, player; player = teamPlayers[i++]; ) { // All players in this team lose (); } for(var color in players) { if(color !== teamColor) { // It means this is another team // Get the players of this team var teamPlayers = players[color]; for(var i = 0,player; player = teamPlayers[i++]; ) { (); // traversal notify other players of win } } } } }; var ReceiveMessage = function(){ // The first parameter of arguments is the message name Get the first parameter var message = (arguments); operations[message].apply(this,arguments); }; return { ReceiveMessage : ReceiveMessage }; })(); // Red Teamvar p1 = heroFactory("aa",'red'), p2 = heroFactory("bb",'red'), p3 = heroFactory("cc",'red'), p4 = heroFactory("dd",'red'); // Blue Team var p5 = heroFactory("ee",'blue'), p6 = heroFactory("ff",'blue'), p7 = heroFactory("gg",'blue'), p8 = heroFactory("hh",'blue'); // All Red Team players die (); (); (); (); // lose:aa lose:bb lose:cc lose:dd // win:ee win:ff win:gg win:hh
We can see the above code; the coupling code between players has been removed, and all logical operations are placed in the intermediary object for processing. Any operation of a player does not need to traverse and notify other players, but just needs to send a message to the intermediary. After the intermediary receives the message, the processing result will be fed back to other player objects. Use the mediator pattern to untie the coupling code between objects; make the program more flexible.
Intermediary model realizes the column of purchasing goods
The following litters are the litters in the book. For example, the litters on Taobao or Tmall are not implemented in this way, and it doesn’t matter. We can change them. We mainly learn the idea of using the intermediary model to achieve it.
First, let’s introduce the business: In the purchase process, you can select the color of the phone and enter the purchase quantity. At the same time, there are 2 display areas on the page, which display the colors and quantity that the user has just selected. There is also a button that dynamically displays the next step. We need to query the stock corresponding to the phone in this color. If the inventory quantity is smaller than the purchase quantity this time, the button will be disabled and display the text with insufficient inventory. Otherwise, the button will be highlighted and can be clicked and displayed if the shopping cart is displayed.
The HTML code is as follows:
Select a color:
<select > <option value="">Please select</option> <option value="red">red</option> <option value="blue">blue</option> </select> <p>Enter the quantity purchased: <input type="text" /></p> The color you chose:<div ></div> <p>The quantity you entered: <div ></div> </p> <button disabled="true">Please select手机颜色和购买数量</button>
First, there is a select selection box on the page, then there is an input purchase quantity input box, and there are 2 display areas, namely the selected color and the displayed area of the input quantity, and the next button operation;
Let's define it first:
Suppose we get the inventory of all color phones from the backend in advance
var goods = { // Mobile phone inventory "red": 6, "blue": 8 };
Next, we will listen to the onchange event of the drop-down box of colorSelect and the oninput event of the numberInput input box, and then handle the corresponding process in these two events.
The regular JS code is as follows:
// Suppose we get the inventory of all color phones from the backend in advancevar goods = { // Mobile phone inventory "red": 6, "blue": 8 }; /* Let's listen to the onchange event of the drop-down box of colorSelect and the oninput event of the numberInput input box respectively. Then, the corresponding handling is made in these two events */ var colorSelect = ("colorSelect"), numberInput = ("numberInput"), colorInfo = ("colorInfo"), numberInfo = ("numberInfo"), nextBtn = ("nextBtn"); // Listen to change events = function(e){ select(); }; = function(){ select(); }; function select(){ var color = , // color number = , // quantity stock = goods[color]; // The current inventory corresponding to the mobile phone in this color = color; = number; // If the user does not select the color, disable the button if(!color) { = true; = "Please select the color of your phone"; return; } // Determine whether the purchase quantity entered by the user is a positive integer var reg = /^\d+$/g; if(!(number)) { = true; = "Please enter the correct purchase quantity"; return; } // If the currently selected quantity is greater than the current inventory quantity, the inventory is insufficient. if(number > stock) { = true; = "Insufficient Inventory"; return; } = false; = "Put into the shopping cart"; }
Although the above code completes the requirements on the page, our codes are all coupled together. Although there are not many problems at present, if the SKU attributes become more and more as the requirements change in the future, for example, when the page adds one or more drop-down boxes, it means choosing the mobile phone memory. Now we need to calculate the color, memory and purchase quantity to determine whether nextBtn shows insufficient inventory or put it in the shopping cart; the code is as follows:
The HTML code is as follows:
Select a color: <select > <option value="">Please select</option> <option value="red">red</option> <option value="blue">blue</option> </select> <br/> <br/> Select Memory: <select > <option value="">Please select</option> <option value="32G">32G</option> <option value="64G">64G</option> </select> <p>Enter the quantity purchased: <input type="text" /></p> The color you chose:<div ></div> You selected memory:<div ></div> <p>The quantity you entered: <div ></div> </p> <button disabled="true">Please select手机颜色和购买数量</button>
The JS code becomes as follows:
// Suppose we get the inventory of all color phones from the backend in advancevar goods = { // Mobile phone inventory "red|32G": 6, "red|64G": 16, "blue|32G": 8, "blue|64G": 18 }; /* Let's listen to the onchange event of the drop-down box of colorSelect and the oninput event of the numberInput input box respectively. Then, the corresponding handling is made in these two events */ var colorSelect = ("colorSelect"), memorySelect = ("memorySelect"), numberInput = ("numberInput"), colorInfo = ("colorInfo"), numberInfo = ("numberInfo"), memoryInfo = ("memoryInfo"), nextBtn = ("nextBtn"); // Listen to change events = function(){ select(); }; = function(){ select(); }; = function(){ select(); }; function select(){ var color = , // color number = , // quantity memory = , // Memory stock = goods[color + '|' +memory]; // The current inventory corresponding to the mobile phone in this color = color; = number; = memory; // If the user does not select the color, disable the button if(!color) { = true; = "Please select the color of your phone"; return; } // Determine whether the purchase quantity entered by the user is a positive integer var reg = /^\d+$/g; if(!(number)) { = true; = "Please enter the correct purchase quantity"; return; } // If the currently selected quantity is greater than the current inventory quantity, the inventory is insufficient. if(number > stock) { = true; = "Insufficient Inventory"; return; } = false; = "Put into the shopping cart"; }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.