Spring入门 02 - 控制反转IoC

IoC全名Inversion of Control,若是中文硬要翻译过来的话,就是「控制反转」。初看IoC,从字面上不容易了解其意义,我以为要了解IoC,要先从Dependency Inversion开始了解,也就是依赖关系的反转。java

 Dependency Inversion在下面这篇文章中有了清楚的解释:http://www.objectmentor.com/publications/dip.pdf框架

 简单的说,在模组设计时,高层的抽象模组一般是与业务相关的模组,它应该具备重用性,而不依赖于低层的实做模组,例如若是低层模组原先是软碟存取模式,而高层模组是个存档备份的需求,若是高层模组直接叫用低层模组的函式,则就对其产生了依赖关系。this

举个例子,例以下面这个程式:spa

#include <floppy.h> .... void save() { .... saveToFloppy() } }

 因为save()程式依赖于saveToFloppy(),若是今天要更换低层的存储模组为Usb碟,则这个程式没有办法重用,必须加以修改才行,低层模组的更动形成了高层模组也必须跟着更动,这不是一个好的设计方式,咱们但愿模组都依赖于模组的抽象,这样才能够重用高层的业务设计。翻译

 若是以物件导向的方式来设计,依赖反转(Dependency Inversion)的解释变为程式不该依赖实做,而是依赖于抽象,实做必须依赖于抽象。咱们来看看下面这个Java程式:设计

BusinessObject.java
public class BusinessObject {
     private FloppyWriter writer = new FloppyWriter();
     .... public void save() {
         ...
         writer.saveToFloppy();
     } 
}

 在这个程式中,BusinessObject的存档依赖于实际的FloppyWriter,若是今天咱们想要将存档改成存至Usb碟,咱们必须修改或继承BusinessObject进行扩展,而没法直接使用BusinessObject。code

若是透过介面的宣告,能够改进此一状况,例如:中间件

public  interface IDeviceWriter { public void saveToDevice(); }   public class BusinessObject { private IDeviceWriter writer; public void setDeviceWriter(IDeviceWriter writer) { this .writer = writer; }      public void save() { .... writer.saveToDevice(); }}

 这样一来,BusinessObject就是可重用的,若是今天我有存储至Floppy或Usb碟的需求,我只要实做IDeviceWriter便可,而不用修改BusinessObject:继承

public class FloppyWriter implement IDeviceWriter { public void saveToDevice() { ....         //实际储存至Floppy的程式码 }}   public class UsbDiskWriter implement IDeviceWriter { public void saveToDevice() { ....         //实际储存至UsbDisk的程式码 }}

 从这个角度来看,Dependency Inversion的意思便是程式不依赖于实做,而是程式与实做都要依赖于抽象。ip

 IoC的Control是控制的意思,其实其背后的意义也是一种依赖关系的转移,若是A依赖于B,其意义便是B拥有控制权,咱们要转移这种关系,因此依赖关系的反转便是控制关系的反转,藉由控制关系的转移,咱们能够得到元件的可重用性,在上面的Java程式中,整个控制权从实际的FloppyWriter转移至抽象的IDeviceWriter介面上,使得BusinessObject、FloppyWriter、 UsbDiskWriter这几个实现依赖于抽象的IDeviceWriter介面。

 从容器(Container)的角度,程式的业务逻辑部份应是能够重用的,不该受到所使用框架或容器的影响,由于咱们可能转移整个业务逻辑至其它的框架或容器,若是业务逻辑过于依赖容器,则转移至其它的框架或容器时,就会发生困难。

 IoC在容器的角度,能够用这么一句好莱坞名言来表明:"Don't call me, I'll call you." 以程式的术语来讲的话,就是「不要向容器要求您所须要的(物件)资源,容器会自动将这些物件给您!」。IoC要求的是容器不侵入应用程式自己,应用程式自己提供好介面,容器能够透过这些介面将所需的资源注至程式中,应用程式不向容器主动要求资源,故而不会依赖于容器的元件,应用程式自己不会意识到正被容器使用,能够随时从容器中脱离转移而不用做任何的修改,而这个特性正是一些业务逻辑中间件最须要的。

相关文章
相关标签/搜索