基于 nest 的 IOC 理解以及基本使用方式

60 阅读4分钟

前言

最近在学习 Nest,所以想要做一个学习记录来督促自己进行学习,也是因为自己记性很差,所以要手写点东西来增强记忆。同时也是希望有人能对我的文章提点意见,让我能加深该方面知识的理解吧

一 对象

  • Controller 对象: 接收 http 请求,调用 Service, 返回响应
  • Service 对象: 实现业务逻辑
  • Repository 对象: 实现对数据库的增删改查
  • DataSource 对象: 数据库链接对象
  • Config 对象: 配置对象

这些对象有着相互依赖的关系

  • Controller 依赖 Service 实现业务逻辑
  • Service 依赖 Repository 来做增删改查
  • Repository 依赖 DataBase 来建立链接
  • Database 从 Config 中拿去用户名 | 密码等配置信息

1-1 对象依赖关系图
以下则是各个对象的创建顺序

// 1. 配置对象
const config = new Config({ username: 'xxx, password: 'xxx' })\

// 2. 数据库链接对象
const database = new DataSource(config)

// 3. 存储对象
const repository = new Repository(database)

// 4. 业务逻辑对象
const service = new Service(repository)

// 5. 请求响应对象
const controller = new Controller(service)

二 定义

从上一个篇章中,我们可以知道,面向对象的设计系统中,它的底层都是有N个对象构成的,各个对象之间通过相互合同,最终实现系统的业务逻辑. 但是如果有大量的对象,并且这些对象直接同时有复杂的多重依赖关系,那么就会出现一个严重的问题,那就是高耦合-如何一个对象出现问题,那么其他对象甚至整个系统都会被影响到.
而 IOC (Inversion of Control 控制反转)的存在就是为这个问题提供了一种解决思路

1 什么是 IOC

简单的来讲, IOC 就是在对象和对象之间插入了一个容器,就像是两个小齿轮中的大齿轮,起着是两个小齿轮一起转动的效果,把两个小齿轮"链接"在一起.
而如果没有这个大齿轮,那么两个小齿轮之间就没有任何联系,这样两个小齿轮的依赖关系就降到了最低,解决了高耦合的问题.

2 IOC(控制反转) 和 DI(依赖注入)

1) IOC

本来一个对象想要获取另一个对象时,我们往往会 new 一个对象出来,去手动创建一个对象来获取该对象中的数据和方法.
但是现在我们通过 IOC 容器直接在 class 上声明该对象依赖了什么对象,然后让工具自己去分析依赖关系,在根据前后关系创建依赖,并进行组装.
实现了创建对象A时,主动把该对象A依赖的对象B之间注入到该对象A中去,不再需要手动创建.
而这种对象A获得依赖对象B的过程,由主动创建变成了被动注入的行为,控制权从A移交到了容器中,所以这里方式就叫做 "控制反转"

2) DI (Dependency Injection)

依赖注入就是 IOC 容器在运行期间,动态的将某种依赖关系注入到对象之中

3) 总结

简单的来讲, IOC 就是解决对象之间解耦的思路,而 DI 则是该思路的实现方式

三 使用 (nest)

1) 基本使用

在 java 和 nest 中,都会使用装饰器(注解)的形式在 class 上进行依赖的声明.
3-1 nest 中 装饰器的使用 Serivce
Injectable() 就代表了可注入,将该 class 放入到了 IOC 容器中去,而
@InjectRepository() 则是该 class 需要的依赖

2) 不同装饰器的定义

  • @Injectable()
    • 代表着既可以被注入(注入其他依赖),同时也可以被注入(被其他对象依赖)
    • 所以 service 使用该装饰器

3-2 nest 中 装饰器的使用 Serivce

  • @Controller()
    • 代表着只能被注入(注入其他依赖)
    • 所以 controller 使用该装饰器

3-3 nest 中 装饰器的使用 controller

  • @Module()
    • 用于处理依赖关系,定义模块的 controller | providers | imports | exports 等
    • controller 代表控制器,就是被 @Controller 装饰的类
    • providers 代表着可以被注入,也可以注入到其他对象,比如这里的 PersonService | AppService
    • **exports **导出 providers, 将该业务的方法暴露出去,给其他业务使用
    • imports 引入其他业务的模块,使用其他业务中的方法

3-4 nest 中装饰器的使用 module
3-5 nest 中使用装饰器,AppController 中使用 PersonService 的方法

四 优缺点

1) 优点

  • 可读性
    • 代码更加简洁
    • 有一个统一的代码模型
  • 可测试性
    • 每个模块都是单独的,所以能够更加容易测试

2) 缺点

  • 生成对象的步骤变得更加复杂了
  • 工程成本相对较大
  • 在运行效率上可能会有一定影响

五 参考文献

[1] Nest 通关秘籍
[2]
【精选】什么是IOC?_贾州的博客-CSDN博客