Spring入门02 - 控制反转IoC

入门 02 - 控制反转IoC

 IoC全名Inversion of Control,如果中文硬要翻译过来的话,就是「控制反转」。初看IoC,从字面上不容易了解其意义,我觉得要了解IoC,要先从Dependency Inversion开始了解,也就是依赖关系的反转。
 Dependency Inversion在下面这篇文章中有了清楚的解释:
http://www.objectmentor.com/publications/dip.pdf
 简单的说,在模块设计时,高层的抽象模块通常是与业务相关的模块,它应该具有重用性,而不依赖于低层的实作模块,例如如果低层模块原先是软盘存取模式,而高层模块是个存盘备份的需求,如果高层模块直接叫用低层模块的函式,则就对其产生了依赖关系。
举个例子,例如下面这个程序:

#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。
如果透过接口的宣告,可以改进此一情况,例如:

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的意思即是程序不依赖于实作,而是程序与实作都要依赖于抽象。
 IoC的Control是控制的意思,其实其背后的意义也是一种依赖关系的转移,如果A依赖于B,其意义即是B拥有控制权,我们要转移这种关系,所以依 赖关系的反转即是控制关系的反转,藉由控制关系的转移,我们可以获得组件的可重用性,在上面的Java程序中,整个控制权从实际的 FloppyWriter转移至抽象的IDeviceWriter接口上,使得BusinessObject、FloppyWriter、 UsbDiskWriter这几个实现依赖于抽象的IDeviceWriter接口。
 从容器(Container)的角度,程序的业务逻辑部份应是可以重用的,不应受到所使用框架或容器的影响,因为我们可能转移整个业务逻辑至其它的框架或容器,如果业务逻辑过于依赖容器,则转移至其它的框架或容器时,就会发生困难。

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值