回答
依賴注入指的是告訴類的依賴關係是什麼樣的模式,而不是要求類知道在哪裏找到它的所有依賴關係。
因此,舉例來說,你從這個去:
public class UserFetcher {
private final DbConnection conn =
new DbConnection("10.167.1.25", "username", "password");
public List<User> getUsers() {
return conn.fetch(...);
}
}
到這樣的事情:
public class UserFetcher {
private final DbConnection conn;
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
這降低耦合的代碼,這是非常有用的,如果你想進行單元測試UserFetcher
。現在,您可以將DbConnection
傳遞給測試數據庫,而不是運行10.167.1.25
的數據庫,而不是UserFetcher
總是。或者,在快速測試中更加有用,您可以傳入一個DbConnection
的實現或子類,它甚至不連接到數據庫,它只是丟棄請求!
但是,這種原始依賴注入使得佈線(提供與它的依賴的對象)更加困難,因爲你已經替換爲使依賴訪問使用全局變量(本地實例化的對象或)的依賴性圍繞整個對象圖。
想象一下UserFetcher
是AccountManager
的依賴關係,其依賴於AdminConsole
。然後AdminConsole
需要的DbConnection
實例傳遞給AccountManager
,並AccountManager
需要將它傳遞給UserFetcher
... 即使沒有AdminConsole
也不AccountManager
需要直接使用DbConnection
!
控制容器的反轉(春,吉斯等)的目的是通過自動佈線(提供)的依賴關係,使依賴注入容易。要做到這一點,你告訴你的IoC容器一次如何提供一個對象(在Spring中,這稱爲bean),並且每當另一個對象請求該依賴關係時,它將由容器提供。
所以我們的最後一個例子可能看起來像這樣與吉斯,如果我們使用構造器注入:
public class UserFetcher {
private final DbConnection conn;
@Inject //or @Autowired for Spring
public UserFetcher(DbConnection conn) {
this.conn = conn;
}
public List<User> getUsers() {
return conn.fetch(...);
}
}
我們必須要配置的IoC容器。在Guice中,這是通過執行Module
完成的;在Spring中,通常通過XML配置應用程序上下文。
public class MyGuiceModule extends AbstractModule {
@Override
public void configure() {
bind(DbConnection.class).toInstance(
new DbConnection("localhost", "username", "password"));
}
}
現在,當UserFetcher
由吉斯或Spring構造時,DbConnection
被自動提供。
Guice有a really good Wiki article關於依賴注入背後的動機,並進一步使用IoC容器。這是值得一讀的。
的策略模式是依賴注入,在那裏你注入邏輯而不是一個對象(即使在Java中,邏輯將在對象封裝)的一個特例。這是一種解耦獨立業務邏輯的方式。
例如,你可能有這樣的代碼:
public Currency computeTotal(List<Product> products) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = beforeTax.times(1.10);
}
但是,如果你想這個代碼擴展到一個新的司法管轄區,以不同的銷售稅方案?您可以注入計算稅的邏輯,如下所示:
public interface TaxScheme {
public Currency applyTax(Currency beforeTax);
}
public class TenPercentTax implements TaxScheme {
public Currency applyTax(Currency beforeTax) {
return beforeTax.times(1.10);
}
}
public Currency computeTotal(List<Product> products, TaxScheme taxScheme) {
Currency beforeTax = computeBeforeTax(products);
Currency afterTax = taxScheme.applyTax(beforeTax);
return afterTax;
}
控制反轉意味着運行時框架將所有組件連接在一起(例如Spring)。依賴注入是IoC的一種形式(我不知道是否存在另一種形式的IoC)(請參見:http://en.wikipedia.org/wiki/Inversion_of_control)。
策略模式是一種設計模式(由GoF定義),其中算法可以被另一個替換(參見:http://en.wikipedia.org/wiki/Strategy_pattern)。這是通過提供幾個相同接口的實現來存檔的。當使用類似Spring的IoC時,如果您有多個接口實現,並且您可以通過配置從實現切換到另一個實現,那麼您正在使用策略模式。
我也推薦閱讀關於這個問題的Spring文檔的介紹章節: Introduction to Spring Framework
前幾段應該做的。
這也鏈接到:Inversion of Control Containers and the Dependency Injection pattern
這也提供了這些非常重要的核心概念的動機觀點。
- 1. 策略模式和依賴注入
- 2. C#依賴注入和策略模式
- 3. 策略模式vs依賴注入
- 4. 在依賴注入中使用策略和工廠模式
- 5. 使用Unity的策略模式和依賴注入
- 6. AngularJS中的依賴注入和控制反轉
- 7. 使用POJO控制和依賴注入的反轉
- 8. 控制的依賴注入和反轉 - 術語
- 9. 在MVC中通過依賴注入學習控制反轉3
- 10. 控制反轉,依賴注入瓦特/ SRP和延遲加載
- 11. C#MongoDb依賴注入和控制反轉
- 12. 控制容器反轉與依賴注入模式之間的區別
- 13. 依賴注入控制器@
- 14. 序列化依賴注入配置/控制反轉
- 15. 是否存在分層方法來控制依賴注入/控制反轉
- 16. 依賴注入和觀察者模式
- 17. 依賴注入和/或工廠模式
- 18. 使用依賴注入MVC 3控制器的命令模式
- 19. 什麼是依賴注入用戶輸入的最佳策略?
- 20. 控制反轉或依賴注入 - 任何人在C中執行它?
- 21. 依賴注入最佳實踐和反模式
- 22. 策略設計模式中不同具體策略之間的依賴關係?
- 23. 在使用依賴注入的同時實例化控制器
- 24. 在這個例子中通過@Produce註釋的依賴注入
- 25. Nugetpacked庫中的控制反轉 - 傳入依賴關係
- 26. 工廠模式在依賴注入
- 27. 依賴注入和模型控制器相互瞭解
- 28. CodeIgniter和依賴注入/控制器注入
- 29. Laravel結構 - 依賴注入控制器
- 30. Laravel控制器依賴注入