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直接作为方法参数传入,比存在实例属性里更清晰,也更易测试(测试时直接传模拟对象即可,无需实例化控制器)。
每次请求创建实例的弊端
- 性能损耗:高并发场景下,频繁实例化和销毁控制器会带来额外的内存开销与垃圾回收压力,累积后会影响服务性能。
- 资源复用困难:若控制器需要初始化复用资源(如数据库连接池、缓存客户端),每次实例化都要重新获取或初始化,会浪费资源并增加请求延迟。
- 测试复杂度高:测试控制器方法时,必须先实例化并传入
req/res/next对象,步骤比直接调用单例方法更繁琐。 - 代码冗余:路由层每次都要写
new MyController(req, res, next).funcX()的逻辑,不如调用单例方法简洁。
内容的提问来源于stack exchange,提问作者harshit kohli
相关产品推荐
相关产品推荐

