依賴注入是否值得

2021-07-24 20:48:51 字數 1977 閱讀 7459

**

依賴注入是否值得? 作者 niclas nilsson ,譯者 郭曉剛

在部落格的世界裡進行了一場關於使用依賴注入(di)之優點和缺點的有趣討論。論題是:依賴注入是否真的值得?

討論始自jacob proffitt,他撰文解釋他的觀點說,依賴注入的伸縮性不好。據proffitt認為,di流行的唯一原因是mocking。

di進來這麼流行的真實原因,和正交性、封裝性或者其他「純粹的」架構考量都沒有關係。真正的原因是很多開發者都用di來幫助使用mock物件進行單元測試。隨你怎麼說,這個因素實際上說服了聰明的開發者選擇di而不是更簡單的實現。

proffitt甚至聲稱di只對單元測試有好處:

不管怎樣,我真的希望人們能夠承認di除了單元測試之外,沒什麼其他有說服力的應用。

不過,proffitt雖然做單元測試,卻不用di。他使用typemock框架。這個框架可以攔截對依賴物件的呼叫,哪怕依賴是在被測試**中建立的。這意味著proffitt不用解耦他的物件也能為單元測試建立mock。

ayende是rhinomocks的創造者,他在自己的部落格上回應說:

雖然能夠方便地編寫mock**是很棒的特性,但這只是主要利益之外的附帶好處,主要的利益是降低了物件間的耦合。我可以修改資料訪問部分的**,而不需要觸及負責工資計算的引擎,這是我得到的主要益處。

nate kohari也回答了proffitt的原帖。kohari不但給出了乙個di的**示例,還詳細闡述了什麼是真正的di:

如果你是gof的愛好者,這其實就是strategy模式。依賴注入(按照我的觀點)本質上是大規模使用的strategy模式。

kohari是ninject di框架的作者,他強烈反對di框架無用的說法:

一旦你開始倚靠di框架來編寫**,連線物件所需的代價就下降到接近於零。於是,要想達到單一職責的目標,其難度會指數級地下降。

在隨後的帖子中,kohari重申了使用框架的重要性,以此來回應proffitt原先認為di的伸縮性不佳的說法:

在真實世界的使用場景中,手工進行的依賴注入的確伸縮性不佳。

proffitt不同意:

你怎麼能說依賴注入(我不是針對整個控制反轉模式,但也未嘗不可。只是還沒輪到。)創造了易於復用的鬆散耦合的單元?di本身就要求呼叫者去提供被呼叫者的所需。任何理性的評價都會認為這是提高了耦合程度。把耦合的負擔丟給框架並不能改變事實,使用乙個物件,仍然需要先給它提供外部的東西。

kohari解釋在大多數情況下,如何建立和注射特定型別的物件只需要配置一次,而且是由框架完成的,不是由呼叫者。

kohari還談到了**的變化能力:

……簡單來說,依賴注入讓你的**更容易改變。這就是它在敏捷社群中流行的原因,他們的整個軟體開發實踐都圍繞著快速變化。

eli lopian是設計出typemock的公司的cto也加入爭論,他對爭論的核心有不同的看法:

當你把di當作是「銀彈」來使用,你就喪失了所用程式語言的一大半能力。你不能用靜態方法,不能用「new」關鍵字,不能用封閉型別。哦,你還要把所有的方法都變成虛擬的。

他還爭辯說,僅僅為了方便變化而使用di,違背了yagni原則。

lopian繼續說:

tdd剛興起時,首先被討論的乙個問題就是「我們是否應該修改**來滿足可測試的要求?」我們應不應該改變**的可見性?我們應不應該改變**的設計?這個問題導致了可測試的**與oo封裝性之間的衝突。開發者們開始為了能夠測試,而把**中的私有部分暴露出來。開頭只是私有方法和屬性,現在擴大到了整個設計。

這是乙個老問題了。有些人認為改變**讓它更容易測試是一件好事;其他人認為這樣做打破了封裝性,因此是壞事。

kohari對封裝與依賴的的關係提出了看法:

這是讓依賴注入物有所值的秘密:當談到依賴的時候,封裝是壞的。

如果出於單元測試的意圖而改變**,能讓耦合變得更鬆散(proffitt對此有所質疑)——這是不是一件好事呢?

鬆散耦合與封裝都是重要的oo特徵,那我們如何作出平衡呢?哪條路才是對的?

檢視英文原文:does dependency injection pay off?

spring 依賴注入 Spring依賴注入

依賴注入 dependency injection,簡稱di 與控制反轉 ioc 的含義相同控制反 在使用spring框架之後,物件的例項不再由呼叫者來建立,而是由spring容器來建立,spring容器會負責控制程式之間的關係,而不是由呼叫者的程式 直接控制,這樣控制權由應用程式轉移到了sprin...

ioc(依賴 依賴倒置 依賴注入)

先看一下這個大佬的部落格 我只是畫個圖 1.依賴 這個很不友好,要換別的player或者meidafile要動operation 2.依賴倒置 這個好很多了,加了兩個介面,要換別的player或者meidafile,不用動operation 3.ioc 控制反轉 控制權是我們使用者自己,如果是spr...

C 依賴注入 setter注入

在文章 c 依賴注入 初步概念了解 中,簡單的介紹了依賴注入常用三種方式 setter注入,建構函式注入,介面注入。在此文章中,使用 具化對setter注入的解釋。setter注入 就是在類a裡面定義乙個c介面的屬性d,在a的上下文通過b例項化乙個物件,然後將這個物件賦值給屬性d。主要就是set 與...