簡體   English   中英

這是依賴注入的正確用法嗎

[英]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.

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