mcpField
M
mediator-pattern

mediator-pattern

github.com/patternsdev开发257609 次安装28 周前更新
代码仓库

关于 mediator-pattern

一项讲解 JavaScript 中介者模式与中间件链的学习技能。它展示如何通过中央协调者转发组件间通信,并以聊天室和 Express.js 为例。

主要功能

  1. 01通过中介者转发请求
  2. 02减少组件间直接依赖
  3. 03串联中间件函数
  4. 04修改请求与响应

适用场景

  1. 01协调聊天室中的消息
  2. 02通过 Express.js 中间件处理请求
  3. 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();
  }
);

太好了!通过一个或多个中间件函数,我们可以一路跟踪并修改请求对象,直到生成响应。

每当用户访问根端点 '/' 时,都会调用这两个中间件回调函数。

中间件模式让我们能够轻松简化对象之间的多对多关系,使所有通信都经过一个中心点。

来源

参考资料

评论

支持 Markdown