2011年9月15日 星期四

Spring 教學 - IoC 的介紹

IoC 是 Spring 的核心,讓 Spring 能夠有效地整合 J2EE 個層級的物件 

在物件的設計方面,讓各層物件的呼叫都面對 "介面" 當系統有一天需要進行變更時,

能夠大大減少對程式碼的修改 只需新增適當的新物見並修改 bean 的配置檔即可 

而 IoC 的觀念即是 "控制反轉" 更進一步說 就是相依關係的轉移 

例如以往的應用程式多半為 高層模組直接相依於低層模組

這樣會造成低層模組的變動必須修改高層模組的程式碼   

加上高層模組多半為那些上頁邏輯的物件所組成的,其設計本應當具有重用性 

也更不能依賴於低層的實現模組

回到前幾句的 "相依關係的轉移 "

可以這樣思考為 實現必須依賴於抽象,而不是抽象依賴於實現


假設 A 相依於 B   那麼代表了 B 擁有控制權,這樣我們需要轉移這種關係

讓控制權由實現的這方轉移到抽象的這方 使應用程式的元件獲得更多的可用性

以 IoC 來說,如果你以 Spring 容器的角度看它  即是 Don't call me,I'll call you

就是你不需要像容器要任何資源物件,容器會自動將它給你

底下先看一下 所謂的 高層模組直接相依於低層模組 的問題


有一個 Driver 類別 他能夠開 BMW 這台車  透過 drive () 方法


public class Driver 
{
	private BMW car = new BMW();     //reference 到一個 BMW 物件
	
	public void drive(){
		car.startRunning();
	}
}
public class BMW
 {
	public void startRunning() {
		System.out.println("Driver start to drive BMW...");
	}

}
但是這個 Driver 不只能夠開 BMW 他還可以開很多其他的車 例如 : Benz...之類的 

那這樣的情況你不就是要修改高層的模組(Driver)了嗎 所以我們要讓 程式相依於介面

既然這樣我們可以先建立一個介面 Car
public interface Car 
{
	public void startRunning();
}
接著讓 BMW Benz.... 的眾多的車子實現類去實做 Car 介面 這樣 Driver 就不需要在面對實現類了,只須面對介面,而實做的細節並不是 Driver 這個類別所關心的 實作的內容已經由各個實現類去實做掉了
public class Driver 
{
	private Car car;
	
	public void drive(){
		car.startRunning();
	}

	public Car getCar() {
		return car;
	}

	public void setCar(Car car) {
		this.car = car;
	}
}
以上的 Driver 類別 針對 car 的個 attribute 給定了一個 getter/setter 所以我們可以寫一個 測試程式來實現一下這個過程
public class Test {
	public static void main(String[] args) 
	{
		Driver driver = new Driver();
		driver.setCar(new BMW());   //driver 要開 BMW
		
		driver.drive();
		
		driver.setCar(new Benz());  //driver 換開 Benz
		
		driver.drive();
	}
}
看到這裡重點來了

Spring 做了什麼事情 ?  Spring 做的就是提供了一個 XML 或是 properties 的檔案

將 Car 的實現類注入給 Driver  ((這裡應該知道為什麼要讓程式依賴於介面了吧!!! 

簡單說你只要寫的 XML 檔(Bean) 就可以任意抽換你想要的車子 (BMW or Benz)

而不需要更改任何一行程式   沒錯 Spring 就是提供了這樣一個的管理功能

而上面有牽扯到 Spring 的另一個重點  DI ( Dependency Injection )

總共有三種依賴注入  下一篇介紹 > Spring 教學 - Bean 的基本裝配

沒有留言:

張貼留言