5 回答

TA貢獻1807條經驗 獲得超9個贊
到目前為止,我發現的最佳定義是James Shore:
對于5美分的概念,“依賴注入”是一個25美元的術語。[...]依賴注入意味著為對象提供其實例變量。[...]。
目前由Martin Fowler的一篇文章,可能證明是有用的,太。
依賴注入基本上是提供對象所需的對象(其依賴關系),而不是讓它自己構造它們。這是一種非常有用的測試技術,因為它允許模擬或刪除依賴項。
可以通過多種方式(例如構造函數注入或setter注入)將依賴項注入到對象中。甚至可以使用專門的依賴注入框架(例如Spring)來做到這一點,但它們當然不是必需的。您不需要這些框架具有依賴注入。顯式地實例化和傳遞對象(依賴關系)與框架注入一樣好。

TA貢獻1828條經驗 獲得超13個贊
依賴注入是一種實踐,其中對象的設計方式是從其他代碼段接收對象的實例,而不是在內部構造它們。這意味著可以替換實現對象所需的接口的任何對象而無需更改代碼,這簡化了測試并改善了解耦。
例如,考慮以下條款:
public class PersonService { public void addManager( Person employee, Person newManager ) { ... } public void removeManager( Person employee, Person oldManager ) { ... } public Group getGroupByManager( Person manager ) { ... }}public class GroupMembershipService() { public void addPersonToGroup( Person person, Group group ) { ... } public void removePersonFromGroup( Person person, Group group ) { ... }}
在這個例子中,執行PersonService::addManager
并且PersonService::removeManager
需要一個實例GroupMembershipService
才能完成它的工作。如果沒有依賴注入,傳統的方法是GroupMembershipService
在構造函數中實例化一個new ,PersonService
并在兩個函數中使用該實例屬性。但是,如果構造函數GroupMembershipService
有多個需要的東西,或者更糟糕的是,有一些初始化的“setter”需要調用GroupMembershipService
,代碼增長得相當快,PersonService
現在不僅取決于GroupMembershipService
而且還取決于其他所有東西。GroupMembershipService
依賴于取決于。此外,鏈接到GroupMembershipService
硬編碼,PersonService
這意味著你不能“假裝”aGroupMembershipService
用于測試目的,或在應用程序的不同部分使用策略模式。
使用依賴注入,而不是實例化GroupMembershipService
你的內部PersonService
,你要么將它傳遞給PersonService
構造函數,要么添加一個Property(getter和setter)來設置它的本地實例。這意味著你PersonService
不再需要擔心如何創建一個GroupMembershipService
,它只接受它給出的那些,并與它們一起工作。這也意味著任何作為接口的子類GroupMembershipService
或實現GroupMembershipService
接口的東西都可以“注入” PersonService
,并且PersonService
不需要知道變化。

TA貢獻1963條經驗 獲得超6個贊
接受的答案是一個很好的答案 - 但我想補充一點,DI非常類似于代碼中經典的避免硬編碼常量。
當您使用某個常量(如數據庫名稱)時,您可以快速將其從代碼內部移動到某個配置文件,并將包含該值的變量傳遞到需要它的位置。這樣做的原因是這些常量通常比其余代碼更頻繁地更改。例如,如果您想測試測試數據庫中的代碼。
DI在面向對象編程領域類似于此。那里的值而不是常量文字是整個對象 - 但是將類代碼從類代碼中創建出來的代碼的原因是相似的 - 對象的更改頻率比使用它們的代碼更頻繁。需要進行此類更改的一個重要案例是測試。
添加回答
舉報