设计模式:Inversion of Control (Dependency Inversion)

        以下文字来源于《从java走向javaee》。

      在模块设计时,高层的抽象模块通常是与业务相关的模块,它应该具有重用性,而不依赖于低层的模块,例如如果低层模块原先是磁盘存取模式,而高层模块是个存档备份的需求,如果高层模块直接调用低层模块的方法,则就对低层模块产生了依赖关系。

       例如下面这段代码:

//...
void save(){
    //...
    saveToFloppy();
}
     由于save()方法依赖于saveToFloppy(),如果要更换低层的存储模式为USB,则这个方法没有办法重用,必须加以修改才行,低层模式的更改造成了上层模式也必须跟着改变,这不是一个良好的设计方式,在设计上希望模式都依赖于模式的抽象,这样才可以重用上层的业务设计。如果以面向对象的方式来设计,依赖反转(Dependecy Inversion)解释变为方法不应该依赖实现,而是依赖于抽象,实现必须依赖于抽象。来看看下面这个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 void 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(){
    //实际存储至USB的方法
  }
}
     从这个角度看,Dependency Inversion的意思即是方法不依赖于实现,而是方法与实现都要依赖于抽象。

     IoC的Control是控制的意思,其背后的意义也是一种依赖关系的转移,如果A依赖于B,其意义即是B拥有控制权,想要转移这种关系,所以依赖关系的反转即是控制关系的反转,由控制关系的转移;可以获得组件的可重用性,在上面的Java方法中,整个控制权从实际的FloppyWriter转移至抽象的接口IDeviceWriter上,使得BusinessObject、FloppyWriter、UsbDiskWriter这几个实现依赖于抽象的IDeviceWriter接口。
    方法的业务逻辑部分应该是可以重用的,不应受到所使用框架或容器的影响,因为可能转移整个业务逻辑到其他的框架或容器,如果业务逻辑过于依赖容器,则转移到其他的框架或容器时,就会发生困难。

      IoC在容器的角度,可以用一句话来说明——“Don't call me, I'll call you”,就是“不要向容器要求所需要的(对象)资源,容器会自动将这些对象给你!”。IoC要求的是容器不侵入方法本身,而方法本身提供好接口,容器可以透过这些接口将所需的资源注入至方法中,方法不向容器主动要求资源,所以不会依赖于容器的组件,方法本身不会意识到正被容器使用,可以随时从容器中脱离转移而不用作任何的修改,而这个特性正是一些业务逻辑中间件最需要的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值