You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript类式服务:每次请求创建控制器实例是否为良策?

控制器实例创建方案对比:每次请求实例化 vs 单例模式

每次请求创建控制器实例的实现

控制器代码

class MyController {
  req: Request;
  res: Response;
  next: NextFunction;

  constructor(req: Request, res: Response, next: NextFunction) {
    this.req = req;
    this.res = res;
    this.next = next;
  }

  func1() {
    // 请求处理逻辑
  }

  func2() {
    // 请求处理逻辑
  }
}

路由代码

router.get('/home', (req, res, next) => {
  new MyController(req, res, next).func1();
});

单例控制器模式的实现

class MyController {
  myfunc(req: Request, res: Response) {
    // 请求处理逻辑
  }
}

export default new MyController();

哪种方案更优?

没有绝对的最优,需结合业务场景判断:

  • 若控制器无需维护跨请求状态,也没有需要复用的初始化资源(如预加载配置、第三方服务客户端),单例模式更高效——它避免了频繁创建销毁实例的开销,代码也更简洁。
  • 若需要在控制器中维护当前请求专属的临时状态,且不想把状态挂载到req对象上,每次请求实例化的方式更直观,能天然隔离不同请求的状态,避免意外污染。

不过在多数Node.js后端场景中,单例模式是主流选择:控制器通常只做请求逻辑分发处理,不需要持有请求级状态,把req/res直接作为方法参数传入,比存在实例属性里更清晰,也更易测试(测试时直接传模拟对象即可,无需实例化控制器)。

每次请求创建实例的弊端

  1. 性能损耗:高并发场景下,频繁实例化和销毁控制器会带来额外的内存开销与垃圾回收压力,累积后会影响服务性能。
  2. 资源复用困难:若控制器需要初始化复用资源(如数据库连接池、缓存客户端),每次实例化都要重新获取或初始化,会浪费资源并增加请求延迟。
  3. 测试复杂度高:测试控制器方法时,必须先实例化并传入req/res/next对象,步骤比直接调用单例方法更繁琐。
  4. 代码冗余:路由层每次都要写new MyController(req, res, next).funcX()的逻辑,不如调用单例方法简洁。

内容的提问来源于stack exchange,提问作者harshit kohli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:55:02