【问题标题】:Are static methods a DI anti-pattern?静态方法是 DI 反模式吗?
【发布时间】:2012-03-11 04:13:39
【问题描述】:

我是一名 Java 开发人员,开始掌握依赖注入的全部威力,我突然意识到没有办法注入静态方法。所以我开始思考:静态方法是 DI 反模式吗?

更重要的是:如果我接受依赖注入,这是否意味着我需要停止编写静态方法?我问是因为在单元测试期间没有办法模拟它们并注入模拟静态,这对我来说是一个巨大的关闭。

编辑:我知道“包装”和注入现有静态方法的常用方法是这样的:

public class Foo {
    public static void bar() { ... }
}

public interface FooWrapper {
    public void bar();
}

public class FooWrapperImpl implements FooWrapper {
    public void bar() {
        return Foo.bar();
    }
}

...但我不是在问如何注入现有的静态方法...我是在问我是否应该完全停止编写它们,如果我的所有代码(从现在开始)都将接受这个概念DI。

此外,我看到很多与此类似的问题,但找不到提出相同问题的完全匹配项。如果您发现这确实是另一个问题的骗局,请指出给我,我将自己关闭这个问题(请不要只是关闭投票!)。

【问题讨论】:

    标签: java dependency-injection mocking static-methods


    【解决方案1】:

    静态方法适用于没有关联状态的事物。一些工厂方法、“纯功能”方法如Math.sin 等都是完全可以接受的静态方法。 java.lang.Mathjava.util.Collections 有许多完全可以接受的静态方法的好例子。

    幸运的是,这些方法不需要依赖注入,也不需要与这些东西交互;它们并不难测试。他们没有需要模拟或任何东西的依赖项。

    另一方面,静态或具有相关静态的静态方法是完全邪恶的。这一种反模式。

    当且仅当它总是在等效输入上返回等效输出时,通常有助于将方法定义为无状态(因此是合法的静态方法)。这清楚地表明,例如数据库查询和文件系统 I/O 使方法成为有状态的,因为它们的输出会根据文件系统或数据库中的内容而有所不同。

    【讨论】:

    • 因此,如果我有一个名为fizz() 的方法,并且在其中我对Widget.buzz() 方法进行静态调用,该方法会访问数据库并对我的本地文件系统进行各种更改,然后如何在不调用调用Widget.buzz() 带来的所有巨大变化的情况下测试fizz()?我的观点是,我认为我应该完全停止编写静态方法,这样我就可以注入正确的Widget 对象(普通与模拟),然后控制buzz() 在运行时触发的“版本”。想法?
    • Widget.buzz() 具有关联的静态状态——数据库,以及隐含的整个文件系统。那是邪恶的。 fizz 可以接受 Widget 参数,您可以模拟 Widget 来测试 fizz
    • 啊,我从没想过数据库或文件系统是有状态的。你用什么标准来定义“有状态”?我认为这是我误解的根源。
    • 数据库的重点是有状态的,否则每次打开计算机都会有一个空数据库。文件系统也是如此。
    • -1 问题是关于 DI,而不是一般静态方法的哲学。顺便说一句,Math 有它邪恶的双胞胎 StrictMath,希望能够与另一个交换一个是合理的。答案是重要的静态方法与 DI 兼容,无论它们是否使用状态。
    【解决方案2】:

    非平凡的静态方法与依赖注入兼容。只需让它们成为单例的实例方法。

    【讨论】:

      【解决方案3】:

      我将把你的问题改写为“当我使用依赖注入时,如何区分 java 方法什么时候应该是静态的,什么时候不应该是静态的?”

      在我看来,区分不应该仅仅基于是否有状态,而是你是否想在测试中模拟该方法。 我知道像 Mockito 这样较新的 BDD 测试框架完全能够模拟静态方法,但这样做会带来巨大的性能成本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-14
        • 2015-08-06
        • 2014-10-08
        • 1970-01-01
        • 2011-06-23
        • 2022-01-18
        • 1970-01-01
        相关资源
        最近更新 更多