编程思想之IOC与DI

被刻印的时光 ゝ 提交于 2019-12-12 00:48:12

什么是IoC

IoC(Inversion of Control),即控制反转,不是什么技术,是面向对象编程中的一种编程思想,可以用来降低代码之间的耦合度。 在JAVA中,当我们需要使用一个对象的时候,传统的方式是

Lang lang = new Lang();

而IoC意味着将你设计好的对象交给容器控制,而不是在你的对象内部直接控制。
举个通俗易懂的例子,网约车出现以前我们是如何叫车的?这能站在路边,招手,叫出租车。还要考虑是否在高峰期,你站的路段会不会有出租车经过,这个过程是麻烦的。传统的程序开发也是如此,在一个对象中,如果想要使用另外一个对象,就必须得到它,自己new一个,有些对象使用完还要将其销毁,比如Connection等。对象与其他接口或类耦合度高。

此时,滴滴这样的网约车平台出现了,所有想载客的私家车在滴滴登记服务类型,身份信息。此时你再想叫车,只需要坐在家里打开APP输入目的地,选择服务类型,滴滴自动安排一个符合要求的车到你面前,为你服务,方便,完美! IOC容器就好比是滴滴,所有的类都会在IoC容器中登记,告诉IoC容器你是个什么东西,你需要什么东西,然后IoC容器会在程序运行到适当的时候,把你需要的东西主动给你,同时也把你交给需要你的东西。

深入分析:
谁控制谁,控制什么: IoC容器控制了外部资源获取,外部资源不仅指对象,还包括文件等。由IoC容器来控制对象的创建。
哪些方面反转了,为什么是反转: 依赖对象的获取被反转了。由容器帮我们查找并注入依赖对象,对象只是被动的接受依赖对象,所以是反转。不同于传统的由我们自己在对象中去控制依赖对象的获取。

什么是DI

DI(Dependency Injection),即依赖注入。由IoC容器决定依赖关系,在程序运行时由容器动态的全权负责组件的装配, 它会把符合依赖关系的对象注入到需要它的对象。也就是通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

DI其实是IoC的更具体描述。大师级人物Martin Folwer认为“Inversion of Control”这个概念比较模糊,于是在2004年给出了一个更能描述其特点的名字:“Dependency Injection”(“依赖注入”)。他的这个解释给出了IOC的具体实现方法:注入。就是由IOC容器在程序运行期间,动态地将某种依赖关系注入到对象中。
原文地址:Inversion of Control Containers and the Dependency Injection pattern

深入分析:
谁依赖于谁: 应用程序依赖于IoC容器
谁注入谁: IoC容器将应用程序所需的外部资源(常量、对象、文件等)注入到应用程序

IOC实现原理

JAVA不同于JS、Python、PHP等动态语言,动态语言允许在程序运行时改变程序结构或变量类型。动态语言修改即生效,而静态语言修改后需要先编译修改才会生效,然后再运行。不过JAVA有着一个动态相关机制:Reflection(反射机制),我们可以利用这个机制实现运行时加载、探知、使用编译期间完全未知的classes,IoC也就是通过JAVA的这种机制实现的。

我们可以把IOC容器看做是工厂模式的改良版,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射机制,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,变成由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,从而达到提高灵活性和可维护性的目的

IOC为我们带来哪些好处

IOC的控制方式就好比是USB外部设备,传统创建对象的方式就好比是内置硬盘,那么USB外部设备有哪些优势呢?

  • USB外部设备在插入主机前与主机没有任何关系,无论两者中任何一方出现什么问题都不会影响另一方的运行。这种特性体现在编程思想中就是可维护性好,便于进行单元测试。代码中每一个组件都可以单独测试,互不影响。从而降低耦合度
  • USB设备与主机之间的无关性带来的另一个好处就是生产USB设备的厂商和生产电脑主机的厂商只需要遵守USB接口标准就可以了,不需要去了解对方的细节。这种特性体现在编程思想中就是每个团队的成员只需要关心自己要去实现的接口规范,不需要去关心其他人的工作进展,你的任务不用依赖于别人的组件可以单独测试。这样在大型项目中就很容易将一个大任务细分为一个个的小任务。从而提高团队间的分工协作能力,提高开发效率
  • 同一个USB设备可以插接到任何支持USB的设备,USB设备可以反复利用。这种特性体现在编程思想中就是,我们可以把使用频率较高的代码段抽离成独立的组件,在项目的不同部分反复调用,这也是面向对象的基本特性。从而提高了代码的可复用性
  • 同USB设备一样,组件具有热插拔特性。IOC将生成对象的方式转为外置方式,也就是在配置文件里定义对象的生成,这样,当我们更换一个实现子类只要修改配置文件就可以了,变得简单多了。从而使组件具有热插拨的特性

其实,反射技术很早就出现了,但一直没有被进一步利用,当时由反射生成对象比正常的生成对象方式至少要慢10倍,后来SUN公司对其进行了改良,速度已经相差不大了,大约是1-2倍的差距。相对于程序的灵活性和可维护性来说,这点效率上的损耗是微不足道的。

参考文章:

什么是IOC、DI
深入理解IOC以及它的优缺点

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!