原文來自:Why use dependency injection
第一次翻譯,如有問題還請留言指出。
E-mail:root@kaaaaai.cn
為什么使用依賴注入?
本文檔介紹了依賴注入的基本知識;它是什么;以及為什么把它加入進你的應用開發(fā)中會是個好的模式?下文將用 DI 這個術語作為依賴注入(dependency injection)的簡稱。
一個真實的例子來說明
與其用抽象的語言描述這個模式,不如用一個簡單的基于視圖控制器的例子來理解它。如果你對抽象描述感興趣,維基百科有一篇很棒的文章。
比如說我們正在開發(fā)一個照片瀏覽應用程序,其中,我們有一個視圖控制器(view controller),顯示從服務器上獲取的一組照片。在這個非常簡單的應用中,我們有一個 PhotosViewController 去展示照片,還有一個 PhotosService 封裝了從我們的服務器請求照片的邏輯。PhotosViewController 實現(xiàn)了視圖邏輯,而 PhotosService 包含 HTTP 請求發(fā)送和響應解析邏輯。沒有使用 DI 時,我們的 PhotosViewController 會在 init 或 viewDidLoad 方法中實例化一個新的 PhotosService 實例,然后在適合的時候使用服務對象來請求照片。
現(xiàn)在我們回過頭來分析一下我們的代碼。在當前狀態(tài)下,PhotosViewController 和 PhotosService 是緊密耦合的。這就給我們留下了一些問題:
- 在不改變
PhotosViewController的情況下,我們不能改變PhotoServie。這在只有兩個類的情況下似乎沒有問題,但在有上百個類的實際場景中,這將大大降低我們的應用迭代速度。 - 在不改變
PhotosViewController的情況下,我們不能替換掉PhotoServie。我們想象一下,我們現(xiàn)在有了一個更好的PhotosServiceV2類,想讓我們的視圖控制器使用,我們就必須深入研究PhotosViewController的實現(xiàn)來進行修改。 - 不引用
PhotoServie我們就無法對PhotosViewController進行單元測試。 - 我們不能同時獨立開發(fā)
PhotosViewController和PhotoServie。這可能看起來不是很大的問題,但在團隊開發(fā)的真實環(huán)境中,我們的工程師將會不斷被阻撓。
讓我們加入 DI 模式到我們的應用。使用 DI,我們將會有第三個類,在 Needle 中,它被稱作 Componet 類,他的作用是實例化 PhotosService 并通過協(xié)議(protocl)傳遞給 PhotosViewController 使用。我們將此協(xié)議(protocol)稱為 PhotosServicing。現(xiàn)在,我們的 PhotosViewController 不再知道任何關于 PhotosService 的具體實現(xiàn)了,它只需使用傳入的 PhotosServicing 協(xié)議來執(zhí)行其邏輯。
使用 DI 后,我們再來看看之前的問題:
- 我們可以自由的改變
PhotosService的實現(xiàn),而不影響我們的PhotosViewController。 - 我們可以簡單地更新 DI
Component類,實例化PhotosService并給PhotosViewController使用,只要它的實現(xiàn)仍然遵從PhotosServicing協(xié)議。這是我們可以自由切換照片服務(photos service)的實現(xiàn)而無需在視圖控制器(view controller)中做任何修改。 - 我們可以通過注入(injecting),也就是傳入一個模擬
PhotosServicing對象來正確地對PhotosViewController進行單元測試。 - 只要定義了
PhotosServicing協(xié)議,我們就可以同時獨立開發(fā)PhotosService和PhotosViewController的實現(xiàn)。
依賴注入術語
在繼續(xù)之前,讓我們定義一些 DI 模式常用的術語。在上面我們簡單的例子中,PhotosService 通常被稱為“依賴關系”(dependency),我們的 PhotosViewController 有時稱為“依賴”或“消費者”。將 PhotosServicing 的實例傳入 PhotosViewController 的行為稱為 "注入"。總之,我們簡單的 DI 設置將 PhotosServicing 依賴關系注入到消費者 PhotosViewController 中。