Spring 核心思想 之反向控制概念解析(有例子)

“反向控制”的意思书上说很简单,开发人员通常把它理解为“实现必须依赖抽象”或者面向接口编程。这句话对于完全不知道的人来说还是完全不知道。。。想起了两个月前的我
下面我把让我理解了这个概念的例子搬上来,与大家共享下。

这个示例主要讲的是如何通过IOC实现具体的业务逻辑,以及如何向不同的存储位置存储数据,我们可能用到的存储方式有三种:
            1.向数据库存储数据(不会在例子中出现)
            2.向XML中存储数据
            3.向文本文件中存储数据
说明概念的思路是:首先我们介绍编写这类程序通常的做法,然后指出这种做法的不足,接着会给出一种比较好的做法,即通过IOC来实现这类功能,最后对这种做法进行总结,使读者一步一步地了解IOC。
由于是讲解概念,所以我们能省的就省。
  首先我们写向XML中存储数据的程序:
通常编写这类程序都是先编写一个向XML存储数据的类XMLData.java,其中saveXML是XMLData类的一个方法,负责向XML存储数据。
//************ XMLData.java *******************//
public class XMLData {
     ...
     //向XML中存储数据
     public void saveXML() {
        ...
     }
}

业务逻辑类Business.java 通过 XMlData.java中的方法向XML中存储数据Business.java的示例代码如下:
//************ Business.java *******************//
public class Business {
     private XMLData db = new XMLData();
     ...
     //向XML中存储数据
     publc void saveData() {
        ...
        db.saveXML();
        ...
     }
}


上面业务逻辑类Business.java和数据存储类XML.java都被设计为实体类,不足之处在于Business类依赖于XML.java类。如果业务改变,用户现在要求向文本文件中存储数据,显然这个时候程序已经不适用了,必须要修改Business类。
   我们先修改为向文本文件中存储数据,再来改变Business类。TXTData.java的示例如下。其中saveTXT()是TXTData类中的一个方法,具体负责向文本文件中存储数据。
//************ TXTData.java *******************//
public class TXTData {
     ...
     //向文本文件中存储数据
     public void saveTXT() {
        ...
     }
}

然后我们要改向TXT中存储数据,所以就必须得修改业务逻辑类Business.java,改为向TXT中存储数据。Business.java的示例代码变为:
//************ Business.java *******************//
public class Business {
     private TXTData db = new TXTData();
     ...
     //向文本文件中存储数据
     publc void saveData() {
        ...
        db.saveTXT();
        ...
     }
}

可以看到,这里对业务逻辑类Business的改动比较大,在这里讲解存储方式的改变,目的是让你明白,这是个多么不好的设计方案:因为每次业务需求的变动都要导致程序的大量修改。
下面我们利用IOC来解决这个问题,编写的思路是:首先我们编写一个存储数据的接口,然后每个具体负责存储数据的类都实现这个接口,如前面的XMLData.java,TXTData.java。而在业务逻辑类Business里,则 针对存储数据的接口编程,并不与存储数据的类建立任何直接的联系。这样一来的话,存储方式发生任何变化都不糊要修改业务逻辑类Business.java。
1,首先我们来编写个存储数据的接口SaveData,让该接口中定义一个方法saveData()用来负责存储数据,这样一来的话,任何一个具体负责存储数据的类都要实现这个方法,而我们的业务逻辑类只针对接口中的saveDate()方法编程就行.
//************ SaveData.java *******************//
public interface SaveData{
    //该方法用来存储数据
    public void saveData();
}

2,接下来我们编写个具体负责向XNL存储数据的类XMLData,该类实现了接口SaveData。
//************ XMLData.java *******************//
public class XMLData implement SaveData{
    //该方法用来存储数据
    public void saveData() {
        //以下是具体负责向XML存储数据的代码
        ...
    }
}

3,编写业务逻辑类Business,该类只针对接口SaveData编码,而不是针对实体类。
//************ Business.java *******************//
public class Business {
    //针对接口SaveData定义变量
    private SaveData db;
    public void setSaveData (SaveData db) {
        this.db = db;
    }
    ...
    //根据注入的存储类,存储数据
    public void saveData() {
        ...
        db.saveData();
        ...
    }
}

4,编写测试类Test
//************ Test.java *******************//
public class Test {
    private Business business = new Business();
    ...
    //根据注入的存储类,存储数据
    public void saveData() {
        ...
        business.setSaveData(new XMLData());
        business.saveData();
        ...
    }
}
通过这种方法,Business就可以重用了,不管采用哪种存储方式来存储数据,Business类都不需要改动了,只需要实现具体的SaveData接口就可以了。
5,编写具体负责向文本文件存储数据的类TXTData,该类实现了接口SaveData。TXTData.java的示例代码:
//************ TXTData.java *******************//
public class TXTData implement SaveData{
    //该方法用来存储数据
    public void saveData() {
        //以下是具体负责向文本文件存储数据的代码
        ...
    }
}
6,业务逻辑类Business在这里就不需要做任何的改变,只需要修改测试类Test:
//************ Test.java *******************//
public class Test {
    private Business business = new Business();
    ...
    //根据注入的存储类,存储数据
    public void saveData() {
        ...
        business.setSaveData(new TXTData());
        business.saveData();
        ...
    }
}
   这些就是例子的全部了,通过上面我们应该了解到一些“面向接口编程”的好处,它使得业务逻辑代码实现了重用,从而实现了如果不是业务逻辑发生变化,就可以不要修改逻辑的相关代码,这里就是IOC的强大之处。
   最后 你可能会有些疑问了:虽然明白了“面向接口编程”的好处,可为什么叫做“反向控制”呢?其实它的意思就是说: 原来由业务逻辑来控制具体的存储方式,即业务逻辑里编写具体的存储方式,面向接口后,不在业务逻辑里编写具体的存储方式了,而是在调用业务逻辑的类里来控制具体的存储方式,好像是由具体的存储方式来控制业务逻辑(给你这种感觉),所以把它叫做“反向控制”
(这篇文章是我看着书本弄出来的,所以不能标原创了, 网上好像缺少这种比较具体的,至少我当时在网上找了很久都没有找到我想要的这种)
首先把这篇文章写给以前惶惶然的自己,写给需要的朋友们,有什么错误可以在评论里提醒下,万分感谢 远方的朋友

猜你喜欢

转载自languang2013.iteye.com/blog/2124568