實例理解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明顯要簡單、靈活、方便。

兩種實現方式的不同,可以用下圖說明:



 

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