我一直在阅读 Factory模式,并且发现了一些文章,建议将Factory模式与依赖注入结合使用,以最大限度地提高可重用性和可测试性.虽然我还没有找到这个Factory-DI混合的任何具体例子,但我将尝试给出一些我的解释的代码示例.但是,我的问题是关于这种方法如何提高可测试性.

我的解释:

所以我们有一个Widget类:

public class Widget {
    // blah
}

我们想要包含一个WidgetFactory来控制Widgets的构造:

public interface WidgetFactory {

    public abstract static Widget getWidget();
}

public class StandardWidgetFactory implements WidgetFactory {

    @Override
    public final static Widget getWidget() {
        // Creates normal Widgets
    }
}

public class TestWidgetFactory implements WidgetFactory {

    @Override
    public final static Widget getWidget() {
        // Creates test/mock Widgets for unit testing purposes
    }
}

虽然这个例子使用的是Spring DI(这是我唯一经验过的API),但是如果我们谈论的是Guice或任何其他的IoC框架并不重要;这里的想法是,我们现在要在运行时注入正确的WidgetFactory实现,具体取决于我们是在测试代码还是正常运行.在Spring中,bean配置可能如下所示:

<bean id="widget-factory" class="org.me.myproject.StandardWidgetFactory"/>
<bean id="test-widget-factory" class="org.me.myproject.TestWidgetFactory"/>

<bean id="injected-factory" ref="${valueWillBeStdOrTestDependingOnEnvProp}"/>

然后,在代码中:

WidgetFactory wf = applicationContext.getBean("injected-factory");
Widget w = wf.getWidget();

这样,环境(部署级别)变量(可能在.properties文件中定义)决定Spring DI是否会注入StandardWidgetFactory或TestWidgetFactory.

我做得对吗?!?这似乎是一个非常多的基础设施只是为我的Widget获得良好的可测试性.并不是说我反对它,但这对我来说只是过度工程化.

我的挂断:

我问这个的原因是因为我将在其他包中有其他对象,其中包含在其中使用Widget对象的方法.也许是这样的:

public class Fizz {
    public void doSomething() {

        WidgetFactory wf = applicationContext.getBean("injected-factory");
        Widget widget = wf.getWidget();

        int foo = widget.calculatePremable(this.rippleFactor);

        doSomethingElse(foo);
    }
}

如果没有这个看似过度设计的庞大设置,我就无法将“模拟小部件”注入到Fizz :: doSomething()的单元测试中.

所以我被撕裂了:一方面,我觉得我正在过度思考 – 我可能正在做的事情(如果我的解释不正确).另一方面,我没有看到任何干净的方式绕过它.

作为一个切向问题,这也引起了我的另一个巨大关注:如果我的解释是正确的(甚至有些正确),那么这是否意味着我们需要每个对象的工厂?!?

这听起来像过度工程!什么是截止?什么是沙子中的线条划分何时使用工厂,什么时候不用?!感谢您对冗长问题的任何帮助和道歉.这让我头晕目眩.

解决方法

DI / IoC有助于测试,因为您可以轻松地决定使用哪种实现,而无需修改使用它的代码.这意味着您可以注入已知的实现来执行特定功能,例如,模拟Web服务故障,保证对函数的良好(或不良)输入等.

工厂不需要使DI / IoC工作.是否需要工厂完全取决于使用细节.

public class Fizz {

    @Inject    // Guice,new JEE,etc. or
    @Autowired // Spring,or
    private Widget widget;

    public void doSomething() {
        int foo = widget.calculatePremable(this.rippleFactor);
        doSomethingElse(foo);
    }

}

java – 依赖注入如何促进可测试性的更多相关文章

  1. Spring IOC容器的Bean管理基于注解属性注入方式

    这篇文章主要为大家介绍了Spring IOC容器的Bean管理基于注解属性注入方式,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Spring IOC容器Bean管理的完全注解开发放弃配置文件

    这篇文章主要为大家介绍了Spring IOC容器的Bean管理完全注解开发放弃配置文件,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. 向Spring IOC 容器动态注册bean实现方式

    这篇文章主要为大家介绍了向Spring IOC 容器动态注册bean实现方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. Spring IOC 能降低耦合的问题分析及解决方法

    这篇文章主要介绍了Spring IOC 为什么能降低耦合,依赖注入是调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成,需要的朋友可以参考下

  5. Spring IOC 常用注解与使用实例详解

    这篇文章主要介绍了Spring IOC 常用注解与使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Spring使用IOC与DI实现完全注解开发

    IOC也是Spring的核心之一了,之前学的时候是采用xml配置文件的方式去实现的,后来其中也多少穿插了几个注解,但是没有说完全采用注解实现。那么这篇文章就和大家分享一下,全部采用注解来实现IOC + DI

  7. 深入了解Spring控制反转IOC原理

    IOC-Inversion of Control,即控制反转。它不是什么技术,而是一种设计思想。这篇文章将为大家介绍一下Spring控制反转IOC的原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  8. spring IOC容器的Bean管理XML自动装配过程

    这篇文章主要为大家介绍了spring IOC容器Bean管理基于XML的自动装配过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. IOC 容器启动和Bean实例化两个阶段详解

    这篇文章主要为大家介绍了IOC 容器启动和Bean实例化两个阶段详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. Spring的IOC原理详情

    这篇文章主要介绍了Spring的IOC原理详情,IOC是Inversion of Control的缩写,多数书籍翻译成“控制反转”,还有些书籍翻译成为控制反向或者控制倒置

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部