什么是IoC呢?
控制反转(Inversion of Control, IoC)是面向对象编程中的一种设计原则,由于理论和实践成熟的相对较晚,所以并没有包含在GoF中。
早在2004年,Martin Fowler提出“哪些方面的控制被反转了?”这个问题。他总结出的结果是依赖对象的获得被反转了,因为大多数应用程序都是由许多类通过彼此协作来实现业务逻辑,这使得每个对象都需要获取与其合作对象(也就是它所依赖的对象)的引用。如果这个获取过程靠自身实现,将导致代码高度耦合并且难以维护和调试。
那么有什么办法即可降低代码的耦合度呢?
- 对象由容器来创建而不是它自己
- 对象本身并不知道它们是如何被配置的
例如:客户端类需要获取用户类
当客户端类需要获取用户类时,可以直接从IoC容器中获取。IoC容器可以用来创建用户类,也可以用于查看用户类是否有依赖对象需要注入,当有用户信息类需要注入时,首先会创建用户信息类,然后将其注入到用户类上。最终,都由容器来管理这些对象的生命周期。
什么是IoC容器呢?
对于大型项目而言,相互依赖的组件很多。如果使用手工方式自己创建和注入依赖的话,效率极低而且经常会出现不可控的场面。因此IoC容器诞生了,IoC容器实际上是一个依赖注入(DI)框架,它能简化工作量,因为它能:
- 动态创建和注入依赖对象
- 管理对象生命周期
- 映射依赖关系
简单来说,IoC容器就是具有依赖注入(DI)功能的容器,主要负责实例化、定位、配置应用程中的对象以及建立这些对象之间的依赖。应用程序无需在代码中new相关对象,而是由IoC容器进行组装。
IoC容器提供最大便利之处在于更加容易实现可插拔可替换的组件,这也使接口驱动开发所带来的优势,根据接口可以提供更加灵活的子类实现,增强代码的健壮性和稳定性。
IoC容器管理的组件一般使是实现了某些接口的类,这些组件又会使用其它某些接口的组件,组件是不需要知道接口的具体实现,因为这一点,组件之间的替换才会如此容易。容器的任务就是帮助我们创建组件具体的实例,并管理它们的依赖关系,以及将所需的具体依赖传递给组件。
IoC有什么优缺点呢?
控制反转是将对象控制权由对象本身转向容器,容器管理着组件的依赖关系并提供对应的依赖对象。优点在于:
- 减少代码的耦合,使应用更加模块化。
- 增加代码的复用率
- 资源更加统一的管理
- 维护代码更为方便,只需修改配置即可。
- 提升程序的测试性
虽然IoC能给开发带来很大的好处,但也并非没有缺点:
- 软件系统引入第三方IoC容器,生成对象的步骤会变得负责,本来只是两者之间的事情,现在又凭空多出一道手续。
- 由于IoC容器生成对象是通过反射方式,在运行效率上是存在一定的损耗的。
IoC有那些实现策略呢?
IoC本身只是一个概念,可以使用不同的方式实现,主要实现策略有两种:
- 依赖查找(Dependency Lookup)
容器提供回调接口和上下文条件给组件,组件必须使用容器提供的API来查找资源和协作对象,仅有的控制反转只体现在回调方法上。容器将调用这些回调方法,从而让应用代码获得相关资源。 - 依赖注入(Dependency Injection,DI)
组件不做定位查询,只提供普通方法让容器去决定依赖关系。容器全权负责组件的装配,它会将符合依赖关系的对象通过Bean属性或构造函数传递给所需的对象。
综上所述,控制反转可以用来减低计算机代码之间的耦合度,常用的方式有依赖注入(Dependency Injection,DI)和依赖查找(Dependency Lookup)。通过控制反转,对象在被创建时由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。