天天看点

IOC和DI解析

IoC

IoC: Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性

IoC容器:实现了IoC思想的容器就是IoC容器

容器:提供组件运行环境,管理组件声明周期(不管组件如何创建的以及组件之间关系如何装配的);

IoC容器不仅仅具有容器的功能,而且还具有一些其他特性—如依赖装配

1、IoC容器特点

【1】无需主动new对象;而是描述对象应该如何被创建即可

IoC容器帮你创建,即被动实例化;

【2】不需要主动装配对象之间的依赖关系,而是描述需要哪个服务(组件),

IoC容器会帮你装配(即负责将它们关联在一起),被动接受装配;

【3】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;

【4】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供某类服务的对象(面向抽象编程),松散耦合,一个对象应当对其他对象有尽可能少的了解,不和陌生人(实现)说话

【5】IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。

2、理解IoC容器问题关键:控制的哪些方面被反转了?

(1)、谁控制谁?为什么叫反转? —— IoC容器控制,而以前是应用程序控制,所以叫反转

(2)、控制什么? —— 控制应用程序所需要的资源(对象、文件……)

(3)、为什么控制? —— 解耦组件之间的关系

(4)、控制的哪些方面被反转了? —— 程序的控制权发生了反转:从应用程序转移到了IoC容器。

DI

DI:依赖注入(Dependency Injection) :用一个单独的对象(装配器)来装配对象之间的依赖关系 。

1、理解DI问题关键

(1)谁依赖于谁? ——- 应用程序依赖于IoC容器

(2)为什么需要依赖? ——- 应用程序依赖于IoC容器装配类之间的关系

(3)依赖什么东西? ——- 依赖了IoC容器的装配功能

(4)谁注入于谁? ——- IoC容器注入应用程序

(5)注入什么东西? ——- 注入应用程序需要的资源(类之间的关系)

更能描述容器其特点的名字——“依赖注入”(Dependency Injection)

IoC容器应该具有依赖注入功能,因此也可以叫DI容器

2、DI优点

【1】帮你看清组件之间的依赖关系,只需要观察依赖注入的机制(setter/构造器),就可以掌握整个依赖(类与类之间的关系)。

【2】组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。

【3】依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。

使用DI限制:组件和装配器(IoC容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。

3、IOC关注服务(或应用程序部件)是如何定义的以及他们应该如何定位他们依赖的其它服务。通常,通过一个容器或定位框架来获得定义和定位的分离,容器或定位框架负责:

(1)保存可用服务的集合

(2)提供一种方式将各种部件与它们依赖的服务绑定在一起

(3) 为应用程序代码提供一种方式来请求已配置的对象(例如,一个所有依赖都满足的对象), 这种方式可以确保该对象需要的所有相关的服务都可用。

现有的框架实际上使用以下三种基本技术的框架执行服务和部件间的绑定:

(1) 类型1 (基于接口): 可服务的对象需要实现一个专门的接口,该接口提供了一个对象,可以从用这个对象查找依赖(其它服务)。早期的容器Excalibur使用这种模式。

(2) 类型2 (基于setter): 通过JavaBean的属性(setter方法)为可服务对象指定服务。HiveMind和Spring采用这种方式。

(3) 类型3 (基于构造函数): 通过构造函数的参数为可服务对象指定服务。PicoContainer只使用这种方式。HiveMind和Spring也使用这种方式。

使用IoC/DI容器开发需要改变的思路

1、应用程序不主动创建对象,但要描述创建它们的方式。

2、在应用程序代码中不直接进行服务的装配,但要配置文件中描述哪一个组件需要哪一项服务。容器负责将这些装配在一起。

其原理是基于OO设计原则的The Hollywood Principle:Don‘t call us, we’ll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的(Passive),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。

IoC容器功能:实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。

本质:

IoC:控制权的转移,由应用程序转移到框架;

IoC/DI容器:由应用程序主动实例化对象变被动等待对象(被动实例化);

DI: 由专门的装配器装配组件之间的关系;

IoC/DI容器:由应用程序主动装配对象的依赖变应用程序被动接受依赖

参考:http://jinnianshilongnian.iteye.com/blog/1471944