簡體   English   中英

全球對抗依賴注入

[英]Globals vs dependency injection

有人說使用依賴注入更好。 這是為什么?

我認為最好是擁有一些全局的,易於訪問的類,而不是龐大的構造函數。

它會以任何方式影響應用程序的速度嗎?

這兩者的混合可能是最好的。

主要優點是解耦 ,這將有助於單元測試。 這種情況完全取決於您如何編寫這些“易於訪問的類”。

這個想法是這樣的。 類通過僅依賴於契約interface )而與實現class )依賴性分離。 在您的實時環境中,您可能永遠不會提供新的實現類,但在您的測試環境中,您很可能會(無論是手工制作的存根,還是來自模擬框架的模擬類)。

應用程序的速度需要分析,但是使用DI框架可能會產生一些開銷,而不是直接與你知道的單例交談。 重要的問題是:這是一個問題嗎? 只有性能期望和分析可以告訴你。 根據我的經驗,其好處遠遠超過可忽略不計的性能損失。

您可能會使用static類和方法作為Globals。 它們沒有任何性能影響。 但是,靜態類不適用於可測試性

靜態方法的缺點是什么?

此外,一旦您的代碼與靜態類(Globals)緊密耦合,您將來無法用替代實現替換它們。 因此,除非在非常簡單的情況下使用,否則Globals可能不是很好的設計。

請注意,靜態類和方法是編譯時綁定,其中DI是運行時綁定 幫助您保持課堂松散耦合

使用“全局”和DI之間存在巨大差異。 首先,路徑通常不會被引導,因為您可能會逐步執行單例服務定位器 今天兩者都被認為是一種反模式。 原因是我們應該設計可測試代碼,當我們需要更改維護代碼庫或滿足新需求時,這給我們帶來了很大的好處。 如果代碼分離,則易於實現可測試性。 你猜測全局行為對解耦沒有幫助,所以例如如果你有代碼加入一個靜態單例,要測試這樣的代碼你需要單例本身,你就不能嘲笑它,這很糟糕因為你不能隨心所欲地強調你的系統。 服務定位器乍一看似乎更好:如果需要測試,您可以逐步模擬服務定位器,但您必須:

  • 事先知道被測系統將向定位器詢問哪些服務
  • 總是創建一個“遞歸模擬”,因為你可能也會模擬返回的服務。

構造函數中的DI是代碼解耦的好方法,因為您非常清楚地說明對象需要運行的內容,並且您可以一目了然地判斷模擬,存根等等。 請注意DI將起作用並幫助您,如果您確保不將DI內核作為代碼依賴於代碼:這將在反模式中轉換DI(您解耦代碼,但是將它綁定到容器),所以記得要學習並真正實現基於模式的根模式 ,這真的會讓你更好地編寫更好的可測試代碼。

我認為關於這個主題的最高職位有一個非常好的DI總結以及如何以正確的方式使用它: 依賴注入(DI)“友好”庫

如果您想深入了解該主題,我可以推薦Mark Seeman撰寫的“.NET中的依賴注入”一書。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM