技术开发 频道

利用Java的反射与代理实现IOC模式



二、    IOC使用的背景
在我们日常的设计中,类与类之间存在着千丝万缕的关系,如果两个类存在着强耦合关系,那么在维护时,一个类的修改很可能会牵动另一个类的关联修改,从而使得我们的维护工作步履维艰。下面让我们来看这样的一个强耦合反面例子。
首先我们建立一个Chinese.java类,该类的sayHelloWorld(String name)方法,用中文对名为name的人问好,其内容如下:
package org.amigo.reflection;
 
/**
 *中国人类.   
 *@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *Creationdate:2007-10-2-上午10:37:17
 */
publicclass Chinese {
    /**
     *用中文对某人问好.
     *@paramname姓名
     */
    publicvoid sayHelloWorld(String name) {
       String helloWorld = "你好," + name;
       System.out.println(helloWorld);
    }
}
下面我们接着建立一个American.java类,该类的sayHelloWorld(String name)方法,用英文对名为name的人问好,其内容如下:
package org.amigo.reflection;
 
/**
 *美国人类.  
 *@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *@version1.0
 *Creationdate:2007-10-2-上午10:41:27
 */
publicclass American {
    /**
     *用英文对某人问好.
     *@paramname姓名
     */
    publicvoid sayHelloWorld(String name) {
       String helloWorld = "Hello" + name;
       System.out.println(helloWorld);
    }
}
    最后我们编写一个测试类对这两个类的sayHelloWorld(String name)方法进行测试,下面是该类的内容:
package org.amigo.reflection;
 
/**
 *HelloWorld测试.
 *@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 *Creationdate:2007-10-2-上午10:45:13
 */
publicclass HelloWorldTest {
 
    /**
     *测试ChineseAmericansayHelloWorld()方法.
     *@paramargs
     *@author<a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
     *Creationdate:2007-10-2-上午10:43:51
     */
    publicstaticvoid main(String[] args) {
       Chinese chinese = new Chinese();
       chinese.sayHelloWorld("阿蜜果");
      
       American american = new American();
       american.sayHelloWorld("Amigo");
    }
}
    观察HelloWorldTest我们可以很清楚的看到,该类与Chinese.java类和American.java类都存在强耦合关系。
上面的例子让我们想到的是在N年以前,当我们需要某个东西时,我们一般是自己制造。但是当发展到了一定的阶段后,工厂出现了,我们可以工厂中购买我们需要的东西,这极大的方便了我们。在上例中,我们都是通过new来创建新的对象,在开发中,这种强耦合关系是我们所不提倡的,那么我们应该如何来实现这个例子的解耦呢?我们接着想到了使用工厂模式,我们需要新建一个工厂类来完成对象的创建,并采用依赖接口的方式,此时需要对代码进行如下修改:
首先建立接口类Human.java,其内容如下。
package org.amigo.reflection;
 
/**
 * 人类接口类.   
 * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 * Creation date: 2007-10-2 - 上午11:04:56
 */
public interface Human {
    /**
     * 对某人问好.
     * @param name 姓名
     */
    public void sayHelloWorld(String name);
}
并将American.java类和Chinese.java类改为实现该接口,即类头分别改成:public class American implements Human和public class Chinese implements Human。
接着编写HumanFactory.java工厂类,其内容为
package org.amigo.reflection;
 
/**
 * 工厂类.   
 * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 * Creation date: 2007-10-2 - 上午11:09:30
 */
public class HumanFactory {
       /**
        * 通过类型字段获取人的相应实例
        * @param type 类型
        * @return 返回相应实例
        */
       public Human getHuman(String type) {
              if ("chinese".equals(type)) {
                     return new Chinese();
              } else {
                     return new American();
              }
       }
}
       最后我们还需要修改测试类HelloWorld.java类,修改后的内容如下:
package org.amigo.reflection;
 
/**
 * HelloWorld测试.
 * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
 * Creation date: 2007-10-2 - 上午10:45:13
 */
public class HelloWorldTest {
 
       /**
        * 测试sayHelloWorld()方法.
        * @param args
        * @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
        * Creation date: 2007-10-2 - 上午10:43:51
        */
       public static void main(String[] args) {
              HumanFactory factory = new HumanFactory();
              Human human1 = factory.getHuman("chinese");
              human1.sayHelloWorld("阿蜜果");
             
              Human human2 = factory.getHuman("american");
              human2.sayHelloWorld("Amigo");
              }
}
观察此例我们可以看到,该类不再与具体的实现类Chinese和American存在耦合关系,而只是与它们的接口类Human存在耦合关系,具体对象的获取只是通过传入字符串来获取,很大程度上降低了类与类之间的耦合性。
但是我们还是不太满足,因为还需要通过chinese和american在类中获取实例,那么当我们需要修改时实现时,我们还需要在类中修改这些字符串,那么还有没有更好的办法呢?让我们在下节中进行继续探讨。
0
相关文章