[英]Is this correct usage of dependency injection
這個問題與這里的問題有關: 可配置的依賴項,易於模擬默認實現。
我的目標是按照 DI 模式設計小型庫。 像下面這樣的代碼是 DI 的正確用法嗎?
ValuesConfiguration 只是 Map 的包裝。 它是一種Value Object,它是由客戶端在運行時創建的,所以不可能使用依賴注入。 以前的版本(在相關問題中)將此配置作為構造函數參數,但它似乎不是“真正的”依賴。
public class Parser {
private ValuesConfiguration configuration;
private ValuesProvider valuesProvider;
private ValuesMapper valuesMapper;
public Parser() {}
public Result parse(String parameterName) {
initDefaults();
List<Values> values = valuesProvider.getValues(parameterName);
...
return valuesMapper.transformValues(values, configuration);
}
private void initDefaults() {
if(valuesProvider == null) {
valuesProvider = DefaultsFactory.getDefaultValuesProvider();
}
}
public void setConfiguration(ValuesConfiguration configuration) {
this.valuesConfiguration = configuration;
}
public void setValuesProvider(ValuesProvider provider) {
this.valuesProvider = provider;
}
...
}
將配置作為 parse() 方法的附加參數不是更好嗎?
依賴注入的替代方法是讓組件發現自己的依賴關系。 在我看來,您使用的是后來的 model。
如果你使用了依賴注入,你只會傳遞它需要的值,而不是更多。 即它的所有依賴項都是注入而不是提取的。 組件不需要知道值的來源。
一個重要提示是您的構造函數不接受任何值,並且您的 setter 傳遞了通用對象,一旦組件正確初始化,就不需要這些對象。
如何將其更改為使用 DI。
public class Parser {
private final ValuesProvider valuesProvider;
private final ValuesMapper valuesMapper;
private final ValuesConfiguration configuratrion;
// all values injected.
public Parser(ValuesProvider valuesProvider, ValuesMapper valuesMapper, ValuesConfiguration configuratrion) {
this.valuesProvider = valuesProvider;
this.valuesMapper = valuesMapper;
this.configuratrion = configuratrion;
}
public Result parse(String parameterName) {
List<Values> values = valuesProvider.getValues(parameterName);
...
return valuesMapper.transformValues(values, configuration);
}
}
我不會將工廠與 DI 結合起來。 這只是令人困惑。 例如,這里我們使用依賴注入:
public void setValuesProvider(ValuesProvider provider) {
this.valuesProvider = provider;
}
但是哦等等,這里我們使用的是工廠:
private void initDefaults() {
if(valuesProvider == null) {
valuesProvider = DefaultsFactory.getDefaultValuesProvider();
}
}
也許我只是比大多數人慢,但對我來說這看起來很精神分裂。 如果要使用 DI,請使用 DI。 設置一個特定的(命名的)默認提供程序並像這樣調用它:
setValuesProvider(myDefaultProvider)
請注意,在這種情況下,您必須仔細記錄它。 或者另一種方法是使用一些聰明的 inheritance(或者可能通過靜態?)能夠將任何ValuesProvider
恢復為其默認 state:
setValuesProvider(myProvider.defaultState())
后者對我來說最有意義。 這里的想法是,無論何時您想使用 Parser,都必須提供ValuesProvider
。 因此,我很可能會通過Parser()
構造函數使用 DI。
DI 並不總是合適的。 使用 DI 工廠並不排除在所有情況下都調用new
。 你的似乎就是其中之一。
我喜歡使用默認值來遵循這種方法:
public Parser(ValuesMapper valuesMapper, ValuesConfiguration configuratrion) {
this(DefaultsFactory.getDefaultValuesProvider(), valuesMapper, configuratrion);
}
// all values injected.
public Parser(ValuesProvider valuesProvider, ValuesMapper valuesMapper, ValuesConfiguration configuratrion) {
this.valuesProvider = valuesProvider;
this.valuesMapper = valuesMapper;
this.configuratrion = configuratrion;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.