java - 依赖项应该注入(inject)一次还是每个对象中

标签 java spring design-patterns dependency-injection

我正在尝试更改一些遗留代码以将 DI 与 Spring 框架结合使用。我有一个具体案例,我想知道哪种是最正确的实现方法。

这是一个java桌面应用程序。有一个 DataManager 接口(interface)用于查询/更改数据存储中的数据。目前只有一种使用 XML 文件进行存储的实现,但将来可以添加 SQL 实现。另外,对于单元测试,我可能需要模拟它。

目前,每一个需要数据管理器的代码都通过使用工厂来检索它。这是工厂的源代码:

public class DataManagerFactory   
{  
    private static DataManagerIfc dataManager;

    public static DataManagerIfc getInstance()
    {
        // Let assume synchronization is not needed
        if(dataManager == null)
            dataManager = new XMLFileDataManager();

        return dataManager;
    }
}

现在我看到了 3 种更改应用程序以使用 DI 和 Spring 的方法。

我。仅在工厂中注入(inject)依赖项,不要更改任何其他代码。

这是新代码:

public class DataManagerFactory  
{
    private DataManagerIfc dataManager;

    public DataManagerFactory(DataManagerIfc dataManager)
    {
        this.dataManager = dataManager;
    }

    public DataManagerIfc getDataManager()
    {
        return dataManager;
    }

    public static DataManagerIfc getInstance()
    {
        return getFactoryInstance().getDataManager();
    }

    public static DataManagerFactory getFactoryInstance()
    {
        ApplicationContext context =
                    new ClassPathXmlApplicationContext(new String[] {"com/mypackage/SpringConfig.xml"});

        return context.getBean(DataManagerFactory.class);
    }
}

以及带有 bean 描述的 XML:

<bean id="dataManagerFactory"
            class="com.mypackage.DataManagerFactory">
    <constructor-arg ref="xmlFileDataManager"/>
</bean>

<bean id="xmlFileDataManager"
    class="com.mypackage.datamanagers.xmlfiledatamanager.XMLFileDataManager">
</bean>

二.更改使用数据管理器的每个类,以便它通过构造函数将其存储为类变量。仅为创建链开始的“根”类进行 Spring bean 定义。

三.与二相同。但对于使用数据管理器的每个类,创建一个 Spring bean 定义,并使用 Spring Ioc 容器实例化每个此类类。

由于我对 DI 概念不熟悉,因此我将感谢每一个建议,这些建议将是正确的和“最佳实践”的解决方案。 非常感谢。

最佳答案

使用选项 3。

第一个选项会使您的代码无法测试。您将无法轻松模拟静态工厂方法以使其返回模拟 DataManager。

第二个选项将强制您让根类了解所有非根类的所有依赖项,以使代码可测试。

第三个选项实际上使用依赖注入(inject),其中每个 bean 只知道其直接依赖关系,并由 DI 容器注入(inject)。

关于java - 依赖项应该注入(inject)一次还是每个对象中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14687722/

相关文章:

java - 如何为 Spring Kafka Listener 创建集成测试

java - xml如何定义数据?

java - 用于实现嵌套 map 之类的数据结构?

design-patterns - 关注点分离与松耦合

design-patterns - 微服务中需要事务发件箱模式

java - 服务器客户端通信在输出流处失败

java - Guavas Futures.transform 的 Spring 实现

java - Spring 事务管理 : Cannot resolve reference to bean 'transactionManager'

java - 无法使用 Spring 配置 JPA

mysql - Spring Hibernate @Data 更新与原始 UPDATE 查询 : Optimistic Lock Exception despite @Transactional?