2014-05-20

Java 注入相依的妙用


軟體專家告訴哦棉,好的程式設計,要寫成「耦合鬆綁(decouple)」,這樣,每個程式單元,才能隨時利用,任意組合。

But.................   How?!

這裡,有一個例子。假設,我們需要開發一個「腳踏車出租管理系統」,供腳踏車店做出租服務。

第一個想開發的功能是:「在螢幕列出店裡所有的腳踏車」。

對於這個功能,我們可以這樣做。

先開發一個: Bike(腳踏車)的 Entity 類別,其程式碼如下。

Bike 類別 

再開發一個:RentABike (租台腳踏車)的類別,用來管理腳踏車出租店的租借業務。在此類別先實作了 2 個方法(method),(1)getBikes:取得店裡所有的腳踏車;(2)getBike :依「序號」取得某一台特定的腳踏車,其程式碼如下。

RentABike 類別 

為了在螢幕上顯示店裡所有的腳踏車,我們又多開發了一個:「CommandLineView」類別,其程式碼如下。

CommandLineView 類別

一般的寫法,我們會很自然地在 CommandLineView 這個類別裡,先用 RentABike 類別建立一個 rentABike 物件。

然後,再利用 rentABike 物件,呼叫方法 - getBikes() ,取出店裡所有的腳踏車。接著在 CommandLineView 類別中,利用迴圈,在螢幕列示出所有的腳踏車。

以上的作法,既簡單,又直覺。但....... 它沒有達到「耦合鬆綁」所要求的程式架構之美!因 CommandLineView 類別與 RentABike 類別,十指緊扣,關係密切啊! ^^"

那該怎麼辦咧?!

Spring 程式高手秘笈》這書,在 Page 1 ~ 9 處,教人如何利用 Interface ,進行「相依注入(Dependency Injection)」,讓 CommandLineView 類別,呼叫 getBikes() 方法的這檔事 ,不是寫死在 CommandLineView 類別中,而是由另一個類別,在 Run Time 時期,負責相依關係的相注入,使 CommandLineView 物件,能呼叫  getBikes() 這方法!

這麼神奇的事,是如何做到的?
  1. 原先 RentABike 類別,能提供其它類別使用的 method ,將它當成是 service ,全包進一個名為 RentABike 的 Interface 中。
  2. 另新增一個「service 類別」 ( ArrayListRentABike ) ,須實作 (implements) 上一個 RentABike Interface 。
  3. 要使用「service 類別」,呼叫其中 method 的這種類別,稱作:「client 類別」, 以此例子而言,就是 CommandLineView 類別,它在類別中,須有一個 property ,用來指向「 service 類別」所產生的物件。
  4. 建立一個類別,負責在 Run Time 時期,執行「相依注入」的工作,這種作法,一般被稱作為 assembler 或 container 機制。在這個例子中,由 RentABikeAssembler 類別擔綱。

此相依注入的作法,可用以下的「類別圖」,來說明各個類別之間的相互關係。

最後,各類別的程式碼,分述如下。

將 RentABike 類別改成 Interface


提供 method 的「Service 類別」:ArrayListRentABike.java


使用 method 的「Client 類別」:CommandLineView.java


注入相依的 Assembler 類別:RentABikeAssembler.java



Run Time 時期,由 RentABikeAssembler 類別,負責「注入相依關係」這檔事。

首先,建立一個「Client 物件」: CommandLineView 物件;然後,建立一個「Service 物件」:ArrayListRentABike。

接著令「Client 物件」- CommandLineView 的 property 指向「Service 件件」 - ArrayListRentABike。最後, CommandLineView 這個「Client 物件」,可以使用 「Service 物件」- ArrayListRentABike ,提供的 getBikes() 方法,取出店裡所有的腳踏車,丟給類別內的方法處理,顯示在螢幕上 。

透過以上「相依注入」的作法,可達成「耦合鬆綁(decouple)」的目標。軟體開發中所使用的各個類別,就能任意組合,隨時依自己的需要來變化及使用。


程式碼下載處: https://github.com/AlanJui/BPANDSVC

沒有留言:

張貼留言