mediator-pattern

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mediator/Middleware Pattern

Mediator/Middleware 模式

The mediator pattern makes it possible for components to interact with each other through a central point: the mediator. Instead of directly talking to each other, the mediator receives the requests, and sends them forward! In JavaScript, the mediator is often nothing more than an object literal or a function.
You can compare this pattern to the relationship between an air traffic controller and a pilot. Instead of having the pilots talk to each other directly, which would probably end up being quite chaotic, the pilots talk the air traffic controller. The air traffic controller makes sure that all planes receive the information they need in order to fly safely, without hitting the other airplanes.
中介者模式让组件能够通过一个中心点——中介者——进行交互。组件之间不再直接通信,而是由中介者接收请求并将其转发!在JavaScript中,中介者通常只是一个对象字面量或函数。
你可以把这个模式比作空中交通管制员和飞行员之间的关系。如果让飞行员直接互相沟通,可能会非常混乱,因此飞行员会与空中交通管制员沟通。管制员确保所有飞机都能收到安全飞行所需的信息,避免发生碰撞。

When to Use

适用场景

  • Use this when multiple objects need to communicate but direct many-to-many relationships would be chaotic
  • This is helpful for implementing middleware chains (e.g., Express.js middleware)
  • 当多个对象需要通信,但直接的多对多关系会导致混乱时使用
  • 这有助于实现中间件链(例如Express.js中间件)

Instructions

实现步骤

  • Create a central mediator that processes requests and forwards them to the appropriate handlers
  • Use the middleware pattern to chain processing functions that can modify requests/responses
  • Keep individual components unaware of each other; they only know about the mediator
  • 创建一个中心中介者,用于处理请求并将其转发给相应的处理程序
  • 使用中间件模式串联处理函数,这些函数可以修改请求/响应
  • 让各个组件互不感知,它们只需要了解中介者

Details

详细说明

Although we're hopefully not controlling airplanes in JavaScript, we often have to deal with multidirectional data between objects. The communication between the components can get rather confusing if there is a large number of components.
Instead of letting every object talk directly to the other objects, resulting in a many-to-many relationship, the object's requests get handled by the mediator. The mediator processes this request, and sends it forward to where it needs to be.
A good use case for the mediator pattern is a chatroom! The users within the chatroom won't talk to each other directly. Instead, the chatroom serves as the mediator between the users.
js
class ChatRoom {
  logMessage(user, message) {
    const time = new Date();
    const sender = user.getName();

    console.log(`${time} [${sender}]: ${message}`);
  }
}

class User {
  constructor(name, chatroom) {
    this.name = name;
    this.chatroom = chatroom;
  }

  getName() {
    return this.name;
  }

  send(message) {
    this.chatroom.logMessage(this, message);
  }
}
We can create new users that are connected to the chat room. Each user instance has a
send
method which we can use in order to send messages.
虽然我们不会用JavaScript来控制飞机,但我们经常需要处理对象之间的多向数据交互。当组件数量较多时,组件之间的通信会变得相当复杂。
与其让每个对象直接与其他对象通信(形成多对多关系),不如让对象的请求由中介者处理。中介者会处理该请求,并将其转发到需要的地方。
中介者模式的一个很好的用例是聊天室!聊天室中的用户不会直接互相交谈,而是由聊天室作为用户之间的中介者。
js
class ChatRoom {
  logMessage(user, message) {
    const time = new Date();
    const sender = user.getName();

    console.log(`${time} [${sender}]: ${message}`);
  }
}

class User {
  constructor(name, chatroom) {
    this.name = name;
    this.chatroom = chatroom;
  }

  getName() {
    return this.name;
  }

  send(message) {
    this.chatroom.logMessage(this, message);
  }
}
我们可以创建连接到聊天室的新用户。每个用户实例都有一个
send
方法,我们可以用它来发送消息。

Case Study

案例研究

Express.js is a popular web application server framework. We can add callbacks to certain routes that the user can access.
Say we want add a header to the request if the user hits the root
'/'
. We can add this header in a middleware callback.
js
const app = require("express")();

app.use("/", (req, res, next) => {
  req.headers["test-header"] = 1234;
  next();
});
The
next
method calls the next callback in the request-response cycle. We'd effectively be creating a chain of middleware functions that sit between the request and the response, or vice versa.
Let's add another middleware function that checks whether the
test-header
was added correctly. The change added by the previous middleware function will be visible throughout the chain.
js
const app = require("express")();

app.use(
  "/",
  (req, res, next) => {
    req.headers["test-header"] = 1234;
    next();
  },
  (req, res, next) => {
    console.log(`Request has test header: ${!!req.headers["test-header"]}`);
    next();
  }
);
Perfect! We can track and modify the request object all the way to the response through one or multiple middleware functions.
Every time the user hits a root endpoint
'/'
, the two middleware callbacks will be invoked.
The middleware pattern makes it easy for us to simplify many-to-many relationships between objects, by letting all communication flow through one central point.
Express.js是一个流行的Web应用服务器框架。我们可以为用户可访问的特定路由添加回调函数。
假设我们想在用户访问根路径
'/'
时为请求添加一个头信息。我们可以在中间件回调中添加这个头信息。
js
const app = require("express")();

app.use("/", (req, res, next) => {
  req.headers["test-header"] = 1234;
  next();
});
next
方法会调用请求-响应周期中的下一个回调函数。我们实际上是在请求和响应之间(或反之)创建了一个中间件函数链。
让我们添加另一个中间件函数,检查
test-header
是否被正确添加。前一个中间件函数所做的更改会在整个链中可见。
js
const app = require("express")();

app.use(
  "/",
  (req, res, next) => {
    req.headers["test-header"] = 1234;
    next();
  },
  (req, res, next) => {
    console.log(`Request has test header: ${!!req.headers["test-header"]}`);
    next();
  }
);
完美!我们可以通过一个或多个中间件函数,在从请求到响应的整个过程中跟踪和修改请求对象。
每次用户访问根端点
'/'
时,这两个中间件回调函数都会被调用。
中间件模式通过让所有通信都流经一个中心点,简化了对象之间的多对多关系。

Source

来源

References

参考资料