在物件的設計方面,讓各層物件的呼叫都面對 "介面" 當系統有一天需要進行變更時,
能夠大大減少對程式碼的修改 只需新增適當的新物見並修改 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 的基本裝配
沒有留言:
張貼留言