2012 依赖注入框架

以下内容来自维基百科的控制反转词条

控制反转英语Inversion of control,缩写为IoC),也叫做依赖注入Dependency Injection,简称DI),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度

 

起源

早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题。他总结出是依赖对象的获得被反转了。基于这个结论,他为控制反转创造了一个更好的名字:依赖注入。许多非凡的应用(比HelloWorld.java更加优美,更加复杂)都是由两个或是更多的类通过彼此的合作来实现业务逻辑,这使得每个对象都需要,与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么如你所见,这将导致代码高度耦合并且难以测试。

IoC 亦称为 “依赖倒置原理”("Dependency Inversion Principle") (Martin 2002:127)。差不多所有框架都使用了“倒置注入(Fowler 2004)技巧,这可说是IoC原理的一项应用。SmallTalkC++, Java 或各种.NET 语言等面向对象程序语言的程序员已使用了这些原理。

控制反转是Spring Framework的核心。

应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取它所依赖的对象的引用,这个责任的反转

技术性说明

术语

Class X 依赖于 class Y 只在如下状况中成立:

  • X 拥有 Y 的控制并且在 X 中使用 Y
  • X 是 Y 的派生物
  • X 依赖于 Z,而 Z 又依赖于 Y (transitivity)

X 依赖于 Y 并不表示 Y 也依赖于 X。但如果 X 和 Y 同时依赖于对方,这种依赖性被称作 循环依赖:这时,X 无法和 Y 分开单独使用,反之亦然。如果在一个面对对象程式中拥有太多的循环依赖,这可能表示这个程式是个欠佳的设计。

打破依赖

如果类X的一个实例对象x调用了类Y的一个实例对象y的方法,那么就称类X依赖于类Y。为了打破这种依赖——“反转”,首先我们可以引入一个接口I(第三方类),接口I中声明了对象y将被对象x调用的所有方法;然后,我们对类Y稍加改造,使其实现接口I;最后,我们把在对象x中对y的调用改为对接口I中对应方法的调用。经过这番改造后,原先的X对Y的依赖关系不存在了,类X和Y现在都依赖于接口I。

这种通过引入接口I来消除类X对Y的依赖的方法,被称作“控制反转”,又叫做“依赖注入”。

需要注意的是,类Y可能还依赖于其他类。在应用反转之前,X依赖于Y,从而也间接依赖于Y所依赖的所有“其他类”。应用控制反转之后,不仅X对Y的直接依赖,且前面提到的那些所有的间接依赖也消除了。而新引入的接口I则不依赖于任何类。

IoC 的类型

Martin Fowler 将 IoC 分成三类。

  • Type 1 : 基于interface (interface injection)。Depending object 需要实作(implement) 特定 interface 以供框架注入所需物件。
  • Type 2 : 基于setter (setter injection)。Depending object 需要实现特定 setter 方法 (但不需要依赖特定interface),
  • Type 3 : 基于constructor (constructor injection)

有的框架,如Plexus 提出Type 4 IoC,以field为基础,惟此法到目前为止尚未被广泛接纳。[1]

各种框架不一定支援以上所有IoC类型。例如SpringFramework 支援Type 1、Type 2 及 Type 3 IoC,而 Plexus支援 Type 2、Type 3 和 Type 4。

控制反转应用实例

C++

Java

使用Java语言写成的程式在控制反转容器(Inversion of Control Container)里应用了控制反转(Martin 2004)。软件需要一个来自容器的物件,而容器自行建构物件和它的附属物。ATG 的 [[en:Dynamo Application Server|Dynamo 应用程式服务器]是第一个利用这途径的环境之一,近来关于这些容器的例子包含了 HiveMindPicoContainerSpring Framework(注意 Spring 是一个完整的企业平台,而非 IOC容器)、Apache ExcaliburSeasarDPML Metro.

.NET

你可能感兴趣的:(依赖注入)