This is the sixth day of my participation in the August More text Challenge. For details, see:August is more challenging
preface
A design pattern that front-end developers use every day is the mediator pattern
Front-end development partners, there is no need to write only page interface? That’s impossible. It can’t all be fake data. Backend partner, is there any write interface that does not need to be displayed? That’s impossible. It’s not worth writing, or who knows what you wrote. How do we interact with each other every day? MVC, you’re familiar with that. MVC uses the intermediary pattern.
It’s a model that we’re all familiar with. In the three-tier structure of MVC, C, as the intermediary, connects M and V. Without the three-tier structure, the page and business logic are coupled together, and the page directly calls the business logic, resulting in more and more bloated business logic and more and more complex page logic, which is not convenient for maintenance and management. Since the adoption of the three-layer structure, THE V is directly separated, and the front and back end each performs its own duties with a clear division of labor. MVC is a typical application of the mediator pattern.
Take a look at wechat, which we use every day.
I have 10 friends, I have to build 10 connections, and you have 20 friends, you have to build 20 connections, how can it be possible, it takes too much resources. In fact, there is a resource server in the wechat end, and all the messages sent by people are sent to the server, and then the message is displayed in the target terminal through the way of push or pull. This resource server is one of the intermediaries.
When it comes to intermediary, we will also think of housing agent, whether renting or buying or selling a house, we need to deal with housing agent. Real estate agents connect buyers and sellers, so buyers and sellers don’t have to practice on their own, they use agents. The intermediary model plays the role of a middleman.
I. What is the mediator model?
The mediator model is the best application of Demeter’s law. Demeter’s law says that an object communicates only with friends, and the more friends, the greater the coupling between them.
What exactly is a friend of a date? See the article — Demeter’s Law — juejin.cn/post/696728…)
So what exactly is a mediator? Let’s take an example. Take supermarket shopping for example, there are all kinds of goods in the supermarket, and there are sales staff to sell the goods. After the goods are sold, they replenish the stock, and if the stock is insufficient, they need to buy. Let’s take a look at which departments are involved, sales department, inventory department and purchasing department. The relationship between them is as follows:
We see an exchange of information between the three departments. Each department may cause relationship and the other two departments, and now, the knowledge has three departments, more reality than the load, increase among two, three or more departments, each department and all other departments interact, will be very messy, and error-prone, then if there is a middleman, specifically to deal with these problems, so, The situation will be much clearer.
This is the core idea of the mediator model.
Mediator Pattern: A mediation class is provided to encapsulate a set of objects and their interactions. The Mediator enables the objects to interact without needing to appear. This mediation class, which typically handles communication between different classes, supports loose coupling, making the code easy to maintain. The intermediary model is a behavioral model.
The structure and realization of the intermediary model
Look at the UML diagram for terminator pattern:
From the picture, we can summarize the following structure:
- Abstract colleagues: The word “colleagues” can be understood as a hierarchical relationship of mutual equality. According to the definition of the intermediary model, every “colleague” is dealing with an intermediary, so you need to define who the intermediary is.
- Specific colleagues: for example, here our sales department, inventory department, procurement department is a mutual level of the department, they can be understood as colleagues.
- Abstract mediator class: Abstract intermediaries define common task behavior
- Specific intermediaries: specific operations that need to be performed. Usually the specific intermediary is dealing with all of the “colleagues”, so all of the “colleagues” classes are defined.
The specific source logic is as follows:
Step 1: Abstract the colleague class.
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Department */
public abstract class IDepartment {
public final static String COMMUNICATION_TYPE_ADD_PRODUCT = "add product";
public final static String COMMUNICATION_TYPE_ADD_PRODUCT_FINISH = "addProductFinish";
public final static String COMMUNICATION_TYPE_PURCHASE = "purchase";
public final static String COMMUNICATION_TYPE_PURCHASE_FINISH = "purchased";
public final static String COMMUNICATION_TYPE_PURCHASEING = "purchaseing";
//private final static String COMMUNICATION_TYPE_ADD_PRODUCT = "add product";
// Quantity of goods
int productNum = 0;
/** * need to communicate with the intermediary */
IMediator mediator;
abstract void setProductNum(Integer productNum);
public IDepartment(IMediator mediator) {
this.mediator = mediator;
}
/** * own work in the department */
public abstract void work(Integer num);
/** * Communication with other departments */
public abstract void communicat(String communicationType);
}
Copy the code
Each department has its own work to do, and communicate with other departments, their own work can be done by themselves, and the communication with other departments, to the intermediary, let the intermediary to forward processing.
Step 2: Specific “colleagues” classes
The specific colleagues in this category are specific departments, sales department, inventory department, procurement department
The sales department
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Sales Department */
public class SaleDepartment extends IDepartment {
public SaleDepartment(IMediator mediator) {
super(mediator);
}
public void setProductNum(Integer productNum) {
this.productNum += productNum;
}
/** Sell goods */
@Override
public void work(Integer num) {
if (productNum > num) {
System.out.println("What's on the shelf now?"+productNum+"Piece, sold." + num + "件");
this.productNum -= num;
if (this.productNum > 20) {
System.out.println("Surplus goods"+productNum+"One piece, plenty of goods.");
} else {
// If the supplement is insufficient, notify us for replenishment
System.out.println("Surplus goods"+productNum+"Not enough."); communicat(COMMUNICATION_TYPE_ADD_PRODUCT); }}else {
// If the goods are not enough, we will notify you of replenishmentcommunicat(COMMUNICATION_TYPE_ADD_PRODUCT); }}@Override
public void communicat(String communicationType) {
if (communicationType.equals(COMMUNICATION_TYPE_ADD_PRODUCT)) {
System.out.println("Goods are short and need replenishment.");
mediator.operate(communicationType, 50);
} else if (communicationType.equals(COMMUNICATION_TYPE_ADD_PRODUCT_FINISH)) {
setProductNum(10);
work(0);
} else if (communicationType.equals(COMMUNICATION_TYPE_PURCHASEING)) {
System.out.println("Insufficient stock, purchasing...."); }}}Copy the code
The inventory department
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Inventory department */
public class StockDepartment extends IDepartment{
public StockDepartment(IMediator mediator) {
super(mediator);
}
public void setProductNum(Integer productNum) {
this.productNum = productNum;
}
@Override
public void work(Integer num) {
System.out.println("Current inventory :"+this.productNum);
// Sign of replenishment success
boolean flag = false;
if (this.productNum >= num) {
System.out.println("Take stock"+num+"件");
this.productNum -= num;
flag = true;
} else {
System.out.println("The stock is short and cannot be replenished. Need to purchase");
flag = false;
}
// This should be an asynchronous notification that the warehouse is insufficient and needs to be purchased
if (productNum > 100) {
System.out.println("The warehouse is fully stocked!");
} else {
communicat(COMMUNICATION_TYPE_PURCHASE);
}
if (flag) {
communicat(COMMUNICATION_TYPE_ADD_PRODUCT_FINISH);
} else{ communicat(COMMUNICATION_TYPE_PURCHASEING); }}@Override
public void communicat(String communicationType) {
if (communicationType.equals(COMMUNICATION_TYPE_PURCHASE)) {
// system.out.println (" The warehouse is short of stock, need to purchase ");
mediator.operate(COMMUNICATION_TYPE_PURCHASE, 0);
} else if (communicationType.equals(COMMUNICATION_TYPE_ADD_PRODUCT_FINISH)) {
// system.out.println (" Inventory replenishment completed ");
mediator.operate(COMMUNICATION_TYPE_ADD_PRODUCT_FINISH, 0);
} else if(communicationType.equals(COMMUNICATION_TYPE_PURCHASEING)) {
// Inventory is insufficient, purchasing....
mediator.operate(COMMUNICATION_TYPE_ADD_PRODUCT_FINISH, 0); }}}Copy the code
The purchasing department
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Purchasing Department */
public class PurchaseDepartment extends IDepartment {
@Override
void setProductNum(Integer productNum) {}public PurchaseDepartment(IMediator mediator) {
super(mediator);
}
@Override
public void work(Integer num) {
this.productNum += num;
System.out.println("Procurement completed");
}
/**
*
*/
@Override
public void communicat(String communicationType) {
mediator.operate(communicationType, this.productNum); }}Copy the code
Step 3: Abstract intermediaries
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Broker interface */
public interface IMediator {
void operate(String type, Integer num);
}
Copy the code
Step 4: Specific intermediaries
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Specific intermediaries */
public class ConcreteMediator implements IMediator {
IDepartment sale;
IDepartment stock;
IDepartment purchase;
@Override
public void operate(String type, Integer num) {
if (IDepartment.COMMUNICATION_TYPE_ADD_PRODUCT.equals(type)) {
// system.out.println (" notify stock replenishment ");
stock.work(num);
} else if (IDepartment.COMMUNICATION_TYPE_PURCHASE.equals(type)) {
// system.out.println (" notify purchasing department to replenish the goods ");
purchase.work(num);
} else if (IDepartment.COMMUNICATION_TYPE_ADD_PRODUCT_FINISH.equals(type)) {
// system.out.println (" Notify sales department and inventory, replenishment completed ");
sale.communicat(type);
} else if (IDepartment.COMMUNICATION_TYPE_PURCHASEING.equals(type)) {
// system.out. println(" Inform sales department, stock is short, purchase is on....") );
sale.communicat(type);
} else if (IDepartment.COMMUNICATION_TYPE_PURCHASE_FINISH.equals(type)) {
System.out.println("Purchase completed, you can pick up the goods."); }}public IDepartment getSale(a) {
return sale;
}
public void setSale(IDepartment sale) {
this.sale = sale;
}
public IDepartment getStock(a) {
return stock;
}
public void setStock(IDepartment stock) {
this.stock = stock;
}
public IDepartment getPurchase(a) {
return purchase;
}
public void setPurchase(IDepartment purchase) {
this.purchase = purchase; }}Copy the code
Step 5: Client invocation
package com.lxl.www.designPatterns.mediatorPattern18.supermarket;
/** * Client */
public class Client {
public static void main(String[] args) {
/ / broker
ConcreteMediator mediator = new ConcreteMediator();
// Sales department
IDepartment sale = new SaleDepartment(mediator);
// Inventory department
IDepartment stock = new StockDepartment(mediator);
// Purchasing department
IDepartment purchase = new PurchaseDepartment(mediator);
mediator.setSale(sale);
mediator.setPurchase(purchase);
mediator.setStock(stock);
// The remaining quantity of goods sold
sale.setProductNum(30);
System.out.println("Inventory of goods :" + sale.productNum);
System.out.println("====== sold 5 pieces ======");
sale.work(5);
System.out.println("====== sold 10 pieces ======");
sale.work(10);
//stock.communicat();}}Copy the code
Step 6: Run the result
Commodity inventory :30 ====== 5 pieces sold ====== 30 pieces of goods on the current shelf, 5 pieces of surplus goods sold, 25 pieces of goods sufficient ====== 10 pieces sold ====== 25 pieces of goods on the current shelf, 10 pieces of surplus goods sold, 15 pieces of goods insufficient, Need to replenish current inventory :0 Inventory is insufficient and cannot be replenished. There are 25 pieces of goods on the current shelf, and 25 pieces of surplus goods have been sold. The goods are sufficientCopy the code
In this way, each department can communicate with the intermediary, instead of having to communicate with each specific department