1、IOC与DI介绍
IOC:全称Inversion Of Control,单看这些单词我们都知道是控制反转的意思。
DI:全称Dependency Injection,可以看出字面意思为依赖注入。
先来看一下枯燥的概念
IOC:控制反转是一种设计原则,旨在减少计算机程序中代码之间的耦合性。 IOC 的核心思想是将对象的创建和管理职责从应用程序代码中剥离出来,交给一个独立的容器去处理。 这样,应用程序代码就可以专注于业务逻辑,而不用关心对象的创建和依赖关系。
DI:依赖注入是一种软件设计模式,也是实现控制反转(IOC)的其中一种技术。这种模式能让一个对象接收它所依赖的其他对象。"依赖"是指接收方所需的对象。"注入"是指将"依赖"传递给接收方的过程。
看完是不是一脸懵逼?
2、案例
单看这么枯燥的概念肯定是不能够懂的,那么接下来就来个小案例辅助理解一下吧。 例如用什么快递寄东西的场景。
传统写法:
javaScript
// 你只能用顺丰快递
class ShunfengExpress {
send(pkg: string) {
console.log(`顺丰寄出:${pkg}`);
}
}
class Person {
sendPackage(pkg: string) {
const sf = new ShunfengExpress(); // 强耦合顺丰快递
sf.send(pkg);
}
}
const person = new Person();
person.sendPackage("箱子"); // 只能走顺丰
有没有发现这种写法有一个问题,小件物品求快的肯定用顺丰我无所谓,但是寄大件我想用德邦快递,那么我必须修改这个Person类里面的方法,所以这样直接写死顺丰快递在里面肯定是不行得咯。
IOC/DI改进写法:
javaScript
// 定义快递接口
interface ExpressService {
send(pkg: string): void;
}
// 实现不同的快递公司
class ShunfengExpress implements ExpressService {
send(pkg: string) {
console.log(`顺丰寄出:${package}`);
}
}
class DeBangExpress implements ExpressService {
send(pkg: string) {
console.log(`德邦寄出:${package}`);
}
}
// 这里不用再关心要用什么快递寄了
class Person {
constructor(private express: ExpressService) {} // 通过构造函数注入依赖
sendPackage(pkg: string) {
this.express.send(pkg); // 直接使用注入的服务
}
}
// 使用
const person1 = new Person(new ShunfengExpress());
person1.sendPackage("箱子"); // 用顺丰
const person2 = new Person(new DeBangExpress());
person2.sendPackage("大件"); // 随时切换成德邦
这里用IOC/DI的思想改造了一波发现没,现在我想用什么快递寄就用什么快递寄,根本不会被限制到,我把快递服务这个依赖通过构造函数的ExpressService注入到里面去是不是瞬间优雅起来了。
3、解释
最后再解释一波,IOC :把"依赖谁"的控制权交给外部,程序只声明需要什么。DI:框架通过构造函数/属性等方式,把依赖对象"注入"到程序中。结合上面的案例来讲的话就是:
控制反转 (IOC) :
markdown
- 原来由 `Person` 强耦合快递的选择(内部 `new Shunfeng()`)
- 现在控制权交给外部(由使用者决定注入哪个快递公司)
依赖注入 (DI) :
markdown
- 快递服务通过构造函数参数(`express: ExpressService`)注入