关于 mediator-pattern
一项讲解 JavaScript 中介者模式与中间件链的学习技能。它展示如何通过中央协调者转发组件间通信,并以聊天室和 Express.js 为例。
主要功能
- 01通过中介者转发请求
- 02减少组件间直接依赖
- 03串联中间件函数
- 04修改请求与响应
适用场景
- 01协调聊天室中的消息
- 02通过 Express.js 中间件处理请求
- 03简化多个组件之间的通信
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ patternsdev/ skills --skill mediator-pattern安装后在 Claude Code 中输入/mediator-pattern确认已加载。
详细介绍
中介者/中间件模式
中介者模式让组件能够通过一个中心点——中介者——彼此交互。组件不再直接相互通信,而是由中介者接收请求,并将其转发出去!在 JavaScript 中,中介者通常只是一个对象字面量或函数。
可以将这种模式与空中交通管制员和飞行员之间的关系进行类比。飞行员不会直接相互交谈(否则场面可能会相当混乱),而是与空中交通管制员沟通。空中交通管制员会确保所有飞机都能收到安全飞行所需的信息,避免与其他飞机相撞。
适用场景
- 当多个对象需要通信,但直接建立多对多关系会造成混乱时使用
- 适用于实现中间件链(例如 Express.js 中间件)
不适用场景
- 两个组件之间直接通信更简单,且系统中的参与者较少时
- 中介者本身变成难以维护的庞大“上帝对象”时
- 事件驱动模式(观察者模式/发布订阅)无需中心协调者就能提供足够解耦时
说明
- 创建一个中心中介者,用于处理请求并将其转发给相应的处理程序
- 使用中间件模式,将能够修改请求/响应的处理函数串联起来
- 让各个组件彼此互不知晓;它们只需要知道中介者
详情
虽然我们希望不会用 JavaScript 来指挥飞机,但我们经常需要处理对象之间多方向传递的数据。如果组件数量较多,组件之间的通信可能会变得相当混乱。
与其让每个对象都直接与其他对象通信,从而形成多对多关系,不如让中介者处理对象的请求。中介者会处理该请求,并将其转发到需要接收请求的地方。
聊天室就是中介者模式的一个典型用例!聊天室中的用户不会彼此直接交谈,而是由聊天室充当用户之间的中介者。
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 方法,可用于发送消息。
案例分析
Express.js 是一个热门的 Web 应用服务器框架。我们可以为用户能够访问的特定路由添加回调函数。
假设我们想在用户访问根路径 '/' 时向请求添加一个标头。我们可以在中间件回调函数中添加这个标头。
const app = require("express")();
app.use("/", (req, res, next) => {
req.headers["test-header"] = 1234;
next();
});
next 方法会调用请求-响应周期中的下一个回调函数。实际上,我们会创建一系列中间件函数,让它们在请求与响应之间运行,反之亦然。
我们再添加一个中间件函数,检查是否正确添加了 test-header。前一个中间件函数所做的修改会在整个链中保持可见。
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();
}
);
太好了!通过一个或多个中间件函数,我们可以一路跟踪并修改请求对象,直到生成响应。
每当用户访问根端点 '/' 时,都会调用这两个中间件回调函数。
中间件模式让我们能够轻松简化对象之间的多对多关系,使所有通信都经过一个中心点。