从简单实例了解Spring的控制反转IoC(Inversion of Control)

来源:互联网 发布:分冶算法 编辑:程序博客网 时间:2024/05/22 08:03
        Spring 的核心是IoC,而IoC模式也只是一种思想,很早以前就有了“依赖倒转原则”和“面向抽象编程”,就像Hibernate的ORM思想一样,重要的是学习人家怎么把思想应用到开发上,或框架上上。这样的设计,又一次地把解耦合的思想灌述进来,实在是很精彩的思想。 这里还是让大家从实例来了解和分享IoC把。
 以对象导向的方式来设计,依赖反转(Dependency Inversion)的解释为“程序不应该依赖实现,而是依赖于抽象接口”。看以下程序: 
public class Business{
    
private FloppyWrite writer= new FloppyWriter();
    ...
    
public void save(){
    ...
        writer.saveToFloppy();
    }
    
}
        Business类的设计中,存盘的需求依赖于实际的FloppyWrite对象,若想要将存储介质改为USB磁盘,则必须修改Business的程序,无法重用Business类。
        通过接口这样申明一个接口:
public interface IDeviceWriter{
        
public void saveToDevice(){
        }

}
        那么Business类可以这样设计了,遇到存盘时,将其依赖于IDeviceWriter接口,而不是依赖于实际的FloppyWriter这个实现:
public class Business{
    
private IDeviceWriter;
    
    
public void setDeviceWriter(IDeviceWriter writer){
        
this.writer=writer;
    }

    
public void save(){
        ...
        writer.saveToDevice();
    }

}

        这样的设计Business类就可以重用了,倘若要存储至Floppy或USB磁盘,这只需要针对这两种需求分别实现接口即可:
        针对Floppy存储设计一个FloppyWriter类:
public class FloppyWriter implement IDeviceWriter{
    
public void saveToDevice(){
        ...
        
//实际存储至Floppy的代码
    }

}
        或针对USB磁盘存储设计一个UsbDiskWriter类:
public class UsbDiskWriter implement IDeviceWriter{
    
public void saveToDevice(){
        ...
        
//实际存储至Floppy的代码
    }

}

        这样的话,采用USB磁盘存储只需编写一个配置程序如下: 
      Business business= new Business();
      business.setDeviceWriter(new UsbDiskWriter());
      business.save();
      而Spring融入这个思想的同时,还将选择实现的配置写入XML,这样更改配置更加方便。

        现在再来理解下Dependency Inversion的解释:“程序不应该依赖实现,而是程序和实现都要依赖于抽象接口”。

        在Martin Fowler的文章中也谈过Dependency Injection(依赖注入),其分三种实现方式:Interface injection,Setter injection(setter方法注入),Constructor injection(构造时注入)。而这里用到的是 Setter方式,也是Spring鼓励的方式。

         是不是已经理解了,是不是感觉心里的特别的舒畅,我也是这样的,很高兴跟大家分享我领悟的!


现在来看这张图片,进行J2EE开发中的DAO设计时应用上这种依赖关系,不用多说了,图片已经把这种关系解释得很微妙了。