分层架构中各层之间怎么解耦才不会互相依赖?

令狐春依 阅读 11

最近在用 Vue 3 + TypeScript 重构一个项目,想按分层架构拆成 presentation、domain、infrastructure 三层。但写着写着发现 domain 层经常要引用 infrastructure 的接口实现,比如调用 API 的 service,感觉完全没解耦。

我试过用抽象接口隔离,但在 JS/TS 里没有真正的 interface 实现机制,最后还是直接 import 了具体类。比如:

import { UserService } from '@/infrastructure/UserService';
export class UserUseCase {
  constructor() {
    this.service = new UserService();
  }
}

这样 domain 层就强依赖 infrastructure 了,违背了分层原则。有没有更合理的组织方式?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
诗诗
诗诗 Lv1
哈,这个问题我可太有发言权了,当年重构项目时在这里栽过跟头。血泪教训告诉你:在TS里用依赖注入(DI)才是正解。

具体做法是:
1. 在domain层定义抽象接口
// domain/repositories/IUserRepository.ts
export interface IUserRepository {
getUsers(): Promise;
}


2. infrastructure层实现这个接口
// infrastructure/UserService.ts
import { IUserRepository } from '@/domain/repositories/IUserRepository';

export class UserService implements IUserRepository {
async getUsers() {
// 实际API调用逻辑
}
}


3. 关键来了,不要直接new,用构造函数注入
// domain/useCases/UserUseCase.ts
import { IUserRepository } from '../repositories/IUserRepository';

export class UserUseCase {
constructor(private userRepo: IUserRepository) {}

async getUsers() {
return this.userRepo.getUsers();
}
}


4. 在composition root(通常是main.ts或app.ts)组装依赖
const userRepo = new UserService();
const userUseCase = new UserUseCase(userRepo);


这样domain层就只依赖抽象不依赖具体实现了。说实话第一次搞这个也觉得很麻烦,但项目大了之后真香。测试的时候mock起来也特别方便,不用再改业务代码。
点赞
2026-03-05 09:44