NestJS特点,MVC、IOC和AOP

84 阅读3分钟

MVC

  1. Model 模型层
  2. View 视图层
  3. Controller 控制层

mvc.png

从项目目录结构看MVC

nestjs目录结构

|-- xxx
|-- src
|   |-- app.controller.ts # app根模块 - 控制器
|   |-- app.module.ts # app根模块
|   |-- app.service.ts # app根模块 - 服务
|   |-- main.ts # 应用程序入口
|   |-- user # user模块
|       |-- user.controller.ts
|       |-- user.module.ts
|       |-- user.service.ts
|       |-- dto
|       |-- entity

eggjs目录结构

├── xxx
├── app/
|   ├── router.js # 用于配置 URL 路由规则
│   ├── controller/ # 用于存放控制器(解析用户的输入、加工处理、返回结果)
│   ├── model/ (可选) # 用于存放数据库模型
│   ├── service/ (可选) # 用于编写业务逻辑层
│   ├── middleware/ (可选) # 用于编写中间件
│   ├── schedule/ (可选) # 用于设置定时任务
│   ├── public/ (可选) # 用于放置静态资源
├── config/

java项目目录结构(spring boot)

src/main/java
 ├─ com.example.demo
 │  ├─ config                   # 配置类
 │  ├─ controller               # 控制器层
 │  ├─ dao                      # 数据访问层
 │  ├─ entity                   # 实体类
 │  ├─ exception                # 异常类
 │  ├─ service                  # 服务层
 │  │  ├─ impl                  # 服务层实现类
 │  │  └─ dto                   # 数据传输对象
 │  └─ utils                    # 工具类
 └─ resources/

MVC与接口请求流程

mvc3.png

IOC - DI

  1. IOC (Inverse Of Control) 控制反转: 一种设计原则,可以用来降低代码耦合度
  2. DI (Dependency Inject) 依赖注入: 最常见的 IOC 实现方案,其他方案: 依赖查找

解决的问题

问题:对象使用链路较长、代码耦合度较高,使用不方便;如下,在controller中使用数据库

const config = new Config({});

const dataSource = new DataSource(config);

const repository = new Repository(dataSource);

const service = new Service(repository);

const controller = new Controller(service);

什么是控制反转(IOC)

juejin.cn/post/725486…

把自己程序一部分的执行控制交给某个第三方。即程序的调用方式,时间,次数等,不由定义方“控制”。

什么是依赖注入(DI)

juejin.cn/post/699990…

将创建对象的任务转移给其他 class,并直接使用依赖项的过程,被称为“依赖项注入”。

容器

如果依赖对象的获取逻辑被反转,具体生成什么依赖对象和什么时候生成都由对象之外某个容器来决定。对象只要在用到依赖对象的时候能获取到就可以了(DI依赖注入)

IOC 就是一个可以自动实例化具体类并且管理各对象之间关系的容器,有了这个自动化的容器,我们关注的就不是具体的关系,而是上升到只需关注抽象之间的关系,而且还可以省去手动实例化。

nestjs中的DI(依赖注入) - 装饰器

@Module、@Controller、@Injectable

// cats.module.ts
@Module({
  imports: [TypeOrmModule.forFeature([Cat])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
// cats.controller.ts
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}
  @Get()
  async findAll() {
    return await this.catsService.findAll();
  }
}
// cats.service.ts
@Injectable()
export class CatsService {
  constructor(@InjectRepository(Cat) private catRepository: Repository<Cat>) {}
  async findAll() {
    return await this.catRepository.find();
  }
}

AOP

  1. 面向切面编程(Aspect Oriented Program): 一种设计思想,剥离与业务无关的横切关注点(日志、过滤器),以提高代码的模块化程度

  2. 实现方式:

  • MiddleWare
  • Guard
  • Pipe
  • Interceptor
  • ExceptionFilter

mvc4.png

nestjs中的切面

  1. MiddleWare - 日志
  2. Guard - 鉴权
  3. Pipe - 参数校验
  4. Interceptor - 常规返回值
  5. ExceptionFilter - 所有异常返回值

nestjs切面顺序

docs.nestjs.com/faq/request…

1.Incoming request
2.Middleware
  2.1 Globally bound middleware
  2.3 Module bound middleware
3.Guards
  3.1 Global guards
  3.2 Controller guards
  3.3 Route guards
4.Interceptors (pre-controller)
  4.1 Global interceptors
  4.2 Controller interceptors
  4.3 Route interceptors
5.Pipes
  5.1 Global pipes
  5.2 Controller pipes
  5.3 Route pipes
  5.4 Route parameter pipes
6.Controller (method handler)
7.Service (if exists)
8.Interceptors (post-request)
  8.1 Route interceptor
  8.2 Controller interceptor
  8.3 Global interceptor
9.Exception filters
  9.1 route
  9.2 controller
  9.3 global
10.Server response