谈谈 对IOC 和 依赖注入的理解

311 阅读3分钟

一 背景

一般来说,软件程序的各个类之间(或者说模块),会存在互相直接调用对象,以及直接使用该对象的方法/变量。比如web的基础开发,业务层调用持久层的对象,是通过new来实例化对象的,这样一来,类之间就产生了耦合性。

因此,在真正的业务中,由于代码复杂程度高,就产生了耦合度过高的问题,也就是说,类之间的依赖程度过高。如果软件设计的耦合度过高,当其中一个类出现bug或者业务上的需求,需要修改代码,那么,其他类也可能会受到影响,进而造成大量的修改,造成可维护性差的问题。本来面向对象的初衷就是,修改某一类的代码但不会影响到其他类。

为了降低软件设计中的耦合度,接触代码中的依赖关系,因此就出现了IOC(控制反转)这一种设计模式。

二 IOC与依赖注入的定义和理解

IOC,一个英文缩写,控制反转的意思。

把通过硬编码"new"产生对象的这种方式,改变为脱离源码,通过把程序中设计的类的定义以及属性和方法,编写到.xml配置文件中,当然,这个会按照一定的格式来编写。在运行的时候,Java会利用"反射"的方式,在外部,根据写好的.xml配置文件中的类定义,生成相应的对象。这就把源码和生成对象隔离了。也就是说不在像之前用new来生成对象了。

所谓反射的方式,也就是根据配置文件中的全类名,来获得该类的对象。

以上仅仅是在外部,产生了对象,为了业务的需求,程序不可能没有依赖关系。我们也会在.xml配置文件中编写类与类之间的关系,比如说Service类引用了Dao类的对象。但值得注意的是,容器(比如Spring)会自动把生成的对象根据编写好的依赖关系,注入到软件中去,即把实例化的Dao类对象注入到Service类下的引用中,从而产生依赖关系。通过这种方式产生依赖关系,大大降低了源代码的耦合度。因为需要改动的时候,只要改动.xml配置文件即可。

这就是"依赖注入",把外部生成的实例化对象注入到源码中该对象的引用中去,使程序之间产生依赖关系。这是IOC的一个重要的实现方式。

以上所说的是IOC完成了底层部分的工作。IOC实际上所有的工作包括: 创建对象,管理对象(通过依赖注入),整合对象,配置对象以及管理对象的生命周期。