听起来高大上的控制反转(IOC)是什么?
大家好,我是前端西瓜哥。今天我们聊聊 IOC,很高大上的东西。
IOC,全称为 Inversion Of Control,即 控制反转。
控制反转是面向对象编程中的一种设计原则,作用是降低各个模块之间的耦合度。
控制反转是思想,不是具体实现。
为什么需要控制反转?
假如 Class A 需要依赖 Class B,我们一般在 A 的构造函数中实例化 B,像这样:
1 | class A { |
这导致了耦合,A 对 B 的依赖,是写在 A 的实现中的。如果你要把 B 换成一个加强版的 BPlus,你就要改 A 的实现。
这时候,我们可以用控制反转。
“控制反转” 这个词怎么理解?就是将原本需要程序员手动控制的程序流程,改成通过框架来控制,从原来的程序员手工控制,改为框架控制。
依赖注入(DI)
DI,英文全称 Dependency Injection,即依赖注入。
依赖注入是控制反转的一种常见实现。
依赖注入这词听起来高大上,很有噱头,实际上实现非常简单,就是将依赖的 Class 先在外面实例化好,再注入到需要它的 Class 中。
像前面的 A 和 B 的依赖关系,我们可以改成:
1 | class A { |
上面是通过构造函数来注入实例对象。我们也可以额外写一个 setB 方法来注入:
1 | class A { |
使用了依赖注入的技巧后,A 和 B 就解耦了,我们可以很方便地这个 B 可以很方便地做替换,如:
1 | const bPlus = new BPlus(); // 在外部实例化 B |
Nestjs 的 IOC
如果你用一些框架,它们可以把依赖注入过程做得更优雅,比如 Nestjs。
1 | import { UserService } from './user.service'; |
在 Nestjs 的 Controller 类中,我们只要在构造函数中声明该类,Nestjs 就能自动扫描注册的依赖列表,从中找出正确的类,并帮你实例化并注入,完全不需要你手动操作。
Nestjs 能做到这点,是利用了 TypeScript 的装饰器和 Reflect.metadata 的能力。
结尾
控制反转,是将原本需要程序员手动维护的依赖控制,反转到框架上去控制。
控制反转是原则,它的常见具体实现是依赖注入(DI)。A 依赖 B,但这个 B 是谁,我不管,我交给框架,你生成好了给我。
此外你还可以用模板设计模式或其他方式。
我是前端西瓜哥,欢迎关注我,学习更多前端知识。
文章首发于我的公众号:前端西瓜哥
本文首发于我的公众号:前端西瓜哥
听起来高大上的控制反转(IOC)是什么?