前言
IoC(Inversion of Control)
,即 “控制反转”
。 IoC
主要是针对对象实例化这个方面。在开发中, IoC
意味着设计好的对象交给容器去控制,而不是使用传统的 new
方式,在对象内部直接控制。首先看一下传统的方式:
传统实例化方式(代码为typescript)
拿网上最常用的造汽车来举例。一辆小汽车通常由 发动机
、 底盘
、 车身
和 电气设备
四大部分组成。四大部分组成。汽车电气设备的内部构造很复杂,简单起见,我们只考虑三个部分: 发动机
、 底盘
和 车身
。
UML类图
如下所示:
接下来开始构建项目,由于构建篇幅过长,拆分到另一篇笔记。
通过执行命令 npx ts-node main.ts
发现输出了 引擎发动了
结果,这正是我们想要的,运行成功!
虽然代码正常运行了,但是从设计的角度来看却存在一下两个问题:
- 在造车的时候不能选择配置,我想要v8引擎,是不能实现的,只能用默认的引擎。
- 在汽车类内部,需要在构造函数中手动一个一个的
new
组件出来。
为了解决第一个问题,我们在构造函数中通过传参的方式来创建组件,由于篇幅限制,拆分到另一篇笔记。
之后通过执行命令 npx ts-node main.ts
发现输出了 引擎发动了
结果,证明我们的修改没问题,并且解决了 问题1
。
由 问题2
引出的解决方案就是 IoC
(控制反转)了。
IoC是什么
IoC
的定义已经在前言中说明了,理解 IoC
思想的关键在于:谁控制谁,控制什么,为何是反转,哪些方面反转了
- 谁控制谁
在传统程序设计中,我们直接在对象内部通过 new
的方式创建对象,是程序主动创建依赖对象。
IoC
是有专门一个 容器
来创建这些对象,即由IoC容器控制对象的创建。
- 控制什么
主要是控制**外部资源(依赖对象)**的获取。
- 为何是反转
有 反转
就有 正转
,传统应用程序是由我们自己在程序中主动控制去获取依赖对象,这叫 正转
。
反转
则是由容器来帮忙创建及注入依赖对象。
所以,在 IoC
的思想中,由于容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是 反转
了。
- 那些方面反转了
显而易见,依赖对象的获取被反转了。
IoC能做什么
IoC
不是一种技术,只是一种思想,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了 IoC
容器后,把创建和查找依赖对象的控制权交给了容器,由容器注入组合对象,所以对象之间是松散耦合。 这样也便于测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
其实 IoC
对编程带来的最大改变不是从代码上,而是思想上,发生了 “主从换位”
的变化。应用程序本来是老大,要获取什么资源都是主动出击,但在 IoC
思想中,应用程序就变成被动了,被动的等待 IoC
容器来创建并注入它所需的资源了。
IoC与DI之间的关系
对于控制反转来说,其中最常见的方式叫做 依赖注入
,简称为 DI
(Dependency Injection)。
所以:IoC是思想,DI是具体实现。关于 DI
的详细介绍,参见笔记