实例理解IoC

         控制反转(IoC:Inversion of Control)是Spring框架的核心,主要用来减少对象间的耦合问题。Martin Fowler曾提问:哪方面的控制被反转了?他总结是依赖对象的获得被反转。因此,他给控制反转提出一个更贴切的名字:依赖注入。Spring的优势是通过一个IoC容器,管理所有的JavaBean,自动注入依赖对象间的引用,减轻程序员的负担。下面通过一个简单的实例,理解Spring中IoC的优势和原理。

       一个parent有两个children,一个son和一个daughter。parent每次出去玩的时候,只能带上一个小孩,因此只能轮流地和他们玩。他们的类的实现如下:

抽象类Child:

public abstract class Child {
	public abstract void play();
}

Child的子类Son:

public class Son extends Child {
	@Override
	public void play() {
		// TODO Auto-generated method stub
		System.out.println("Parent is playing with the son!");
	}
}

Child的子类Daughter:

public class Daughter extends Child {
	@Override
	public void play() {
		// TODO Auto-generated method stub
		System.out.println("Parent is playing with the daughter!");
	}
}

类parent:

public class Parent {
	private Child child;

	public Child getChild() {
		return child;
	}

	public void setChild(Child child) {
		this.child = child;
	}

	public void playWithChild() {
		child.play();
	}

}

 

有如下两种应用场景需求:

情况一:parent带son出去玩

情况二:parent带daughter出去玩

 

下面比较两种实现方法:

实现方法一:常规实现

import org.junit.Test;
import junit.framework.TestCase;

public class ParentTest extends TestCase {

	@Test
	public void testPlayWithChild() {
		Parent parent = new Parent();

		// 情况一:
		// 如果Parent和Son玩,则创建Son实例,并调用属性方法传递引用
		Son son = new Son();
		parent.setChild(son);

		// 情况二:
		// 如果Parent和Daughter玩,则创建Daughter实例,并调用属性方法传递引用
		// Daughter daughter = new Daughter();
		// parent.setChild(daughter);

		parent.playWithChild();
	}
}

实现方法二:IoC实现

beans.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<!--
  		情况一:Parent带Son出去玩
   	 -->
	<bean id="child" class="Son">
	</bean>

	<!--
		情况二:Parent带Daughter出去玩 
	<bean id="child" class="Daughter"> </bean>
	-->

	<bean id="parent" class="Parent" autowire="byType">
	</bean>

</beans>

JUnit测试程序:

import org.junit.Test;
import junit.framework.TestCase;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ParentTest extends TestCase {

	@Test
	public void testPlayWithChild() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		Parent parent = (Parent) ctx.getBean("parent");

		parent.playWithChild();
	}
}

两种实现方式的比较:
1. 常规方法中,parent依赖的child引用,通过调用属性方法来传递;IoC实现中,通过byType由IoC容器自动注入parent所依赖的引用。

2. 常规方法除了要创建实例,还要手动传递parent依赖的对象的引用;IoC只需要修改xml配置文件

3. 测试代码中红色标记部分,表示针对两种情况需要改动的代码。IoC明显要简单、灵活、方便。

两种实现方式的不同,可以用下图说明:



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章