What’s dependency injection?

Han
Mar 6, 2021

--

由於連日大雨,突然心血來潮,想重新溫習一下相關的知識,於是此文誕生。

Photo by Inge Maria on Unsplash

近期工作上剛好比較常在跟同事討論到一些專案結構和設計問題,但是常常會發生臨時忘掉如何解釋那些專有名詞和原則的窘境。覺得這樣很不行,決定趁現在剛看完後,寫點東西紀錄。

依賴注入 (DI, Dependency Injection)

簡單名詞解釋(可略過):

Dependency,依賴,顧名思義,一個物件需要另一個物件存在;如果不存在,這個物件就不能獨立運作。

Injection,注入,就是將另一個物件直接傳入需要使用這個物件的地方,這裡使用 Injection 這個關鍵字形容這個行為。

上面只是簡單的根據兩個英文字單獨的意思拆解,其實這應該要視為同一個字,因為是形容一個完整的行為。基本上可以無視各自文字的解釋,專注於這個名詞代表的意思即可。當然,因為母語是中文的關係,可能還是會習慣拆兩個單字,如果可以幫助記憶,個人倒是覺得也無不可。

為何要用:

基於物件導向設計(OOP),應用程式都是以類別的實例(就是物件),來實現各種功能,這種情況下,必然會出現其中一個物件需要另外一個物件的功能。

物件之間的互相依賴,容易造成高偶合(High coupling)的問題,一旦修改一個物件,很大的可能會需要修改一大堆連帶的物件。這種情況下,造成的風險可能會完全無法預期。

為了解決耦合問題,所以才需要用 Dependency Injection。

如何使用:

簡單說,藉由外部傳入的物件應該在外面就先實例化(Instanced)完成(new ClassName()),然後在需要的地方理應用內部變數來存放後使用。

* (實例化在OOP語言就是 new Car(),Python 這邊就是 Car())

Python example for DI

Dependency Injection 的大原則就是 Injection (注入)的物件不應該在內部進行實例化。以前我不懂為何要在外部進行。說穿了,就是因為如果在內部進行實例化,一旦需要修改名稱或是實例化的參數。舉凡修改參數的數量、類型以及順序。這些全部都要根據新的格式進行改動,這個在大型系統中是非常複雜且成本很高的一件事情。所以,就應該是設計一個良好的物件可供需要的物件使用。並且不隨意更動其成員(Function or Parameter)。

而制定規範,並且根據規範實作,這就是介面(Interface)負責的項目。因此,多數時候,我們會先制定一個共用的介面,需要實作的類別們,都需要先實現介面的成員。

以上為介面隔離原則 (ISP, Interface Segregation Principle) 的基本應用。

最終,需要每一個被別的物件呼叫的物件們,都擁有介面制定好的成員。這個解決方案,就是依賴反轉 (DIP, Dependency Inversion Principle)。

總結:

筆記到後面,突然發現其實我早就在很多地方用過它了,只是一直沒有太多深入思考這兩者之間的關聯性。

由於此文作為一個快速筆記,加強記憶為用。

參考:

https://www.freecodecamp.org/news/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f/

https://ithelp.ithome.com.tw/articles/10191761

--

--