IoC & DI
Dependency Injection 依賴注入 (DI)
參考資料:Dependency Injection 筆記(https://www.huanlintalk.com/post/2011-10-14-dependency-injection-1/)
如何向五歲的孩童解釋 DI?
該帖的問題是:「如何向五歲的孩童解釋 DI?」在眾多回答中,有位名叫 John Munch 的仁兄假設提問者就是那五歲的孩童而給了如下答案:
物件導向設計原則
SRP(Single Responsibility Principle):單一責任原則。一個類別應該只有一個責任。
OCP(Open/Closed Principle):開放/封閉原則。對開放擴充,對修改封閉。
LSP(Liskov Substitution Principle):里氏替換原則。物件應該要可以被它的子類別的物件替換,且完全不影響程式的既有行為。
ISP(Interface Segregation Principle):介面隔離原則。多個規格明確的小介面要比一個包山包海的大型介面好。
DIP(Dependency Inversion Principle):相依反轉原則。依賴抽象型別,而不是具象型別。
Inversion of Control 控制反轉(IoC)
一般的做法: 上層呼叫某個高階模組的方法,該方法 new 一個低階模組的物件出來用。 這樣這個方法就會綁定這個物件。
但如果有多種類似的物件呢?
利用 介面(interface) 來解耦,將這些類別抽象化(共通的部分抽出來,做成介面),使這些共通性成為規格,而那些物件再實作這個介面、實作這些規格。
DIP: 高階模組不應依賴低階模組,它們應該去相依抽象層。 抽象層不應依賴實作細節,而是實作細節去依賴抽象層。
之後在使用時,由於不能new 出介面,那麼物件從何而來? 答案是由上方 new 出想要的物件,傳到該方法去讓底部使用。
原本在底部 new 物件出來,改成了從上層傳物件到底部去用,所以控制反轉了。
Dependency Injection 依賴注入 (DI)
一種設計模式和原則,用來寬鬆耦合。
以上方舉例來說,由呼叫端將相依物件透過建構函式,注入至另一個物件的作法,是DI的一種常見寫法,叫作「建構式注入」(Constructor Injection)。
DI的三種注入方式: 1.建構式注入(Constructor Injection) 2.屬性注入(Property Injection) 3.方法注入(Method Injection)
Note: 每當需要注入相依物件時,一般建議優先考慮「建構式注入」,因為其用法對呼叫端來說相當明確、直覺——建立物件時就要一併傳入所有相依物件,所以呼叫端透過建構函式便可得知某物件相依於哪些第三方元件。
介面導向設計
原本相依的物件,現在都透過相依於介面。
當要測試時,再從外部將實作介面的測試物件傳入,去驗證其商業邏輯。
這個把初始化動作,由原本目標物件內,轉移到目標物件之外,稱作「控制反轉」,也就是 IoC。
這個把依賴的物件,透過目標物件公開建構式,交給外部來決定,稱作「依賴注入」,也就是 DI。
而 IoC 跟 DI,其實就是同一件事:讓外部決定目標物件的相依物件。
而這個介面,也可以是目標物件的擴充點,或是接縫。
Last updated