-1

首先,我使用的是 Scala,但任何 Java 方法都可以。(为了便于理解,我将使用 Java 代码作为示例。)

假设我有一个Connection接口及其实现RealConnectionFakeConnection.

我想在我的应用程序中有两个条目:一个发布条目和一个测试条目。我想像往常一样对我的应用程序进行编码,然后开始我的测试,该测试使用发布版本所做的所有类,但有一个例外,它使用FakeConnection而不是RealConnection.

我的应用程序通过Connection.get().

我不想要的是这样的:

public static Connection get() {
    if ( isReleaseVersion )
        return new RealConnection();
    return new FakeConnection();
}

我希望我的应用程序代码不会被这种代码污染。

可能有一个Config对象,如:

public static Connection get() {
    return Config.getConnectionFactory().get();
}

Config这里的问题是每次我想测试时都需要更改课程。如果没有其他方法,我可能会使用这种方法。

我不想使用的是二传手。我想处理final变量或函数!不是这样的:

public class TestEntry {
    public static void main(String... args) }
        Config.connectionFactory = new FakeConnectionFactory();
        Config.databaseConnection = new FakeDatabaseConnection(); // Singleton, no factory needed.
        MyApplication.start(args); // the ReleaseEntry is somewhere else!
    }
}

我也不想使用的是Guice. 每次我想进行测试时,我都必须重新定义我的模块。另外,我一般不会在 Scala 中使用它。

Reflection有可能,但错误只会出现在运行时,所以它不是一个非常 .

有没有其他方法可以完成我想要的?

我必须顺其自然Config吗?

问候。

4

1 回答 1

1

您的问题包含一个矛盾:

你想让某些东西在全球范围内可用

我的应用程序访问Connection通过Connection.get()

不使用变量存储的

我不想使用的是二传手。我想处理最终变量或函数!

然而,您想在运行时提供此实现。

其他人提到了“依赖注入”,这是“控制反转”的一种形式,你的问题中的要求告诉我这就是你想要的。

如果您不想使用变量,则必须使用连接将正确的实例传递给组件。使用 Scala,您可以选择传递它implicitly而不是explicitly.

class MyComponent(name:String)(implicit c:Configuration)

implicit val configuration = new TestConfiguration

//note that the configuration is passed in implicitly
val m = new MyComponent("foo")

此要求也使其他选项变得棘手:

反射是可能的,但错误只会出现在运行时

如果您不想更改任何要求,您可能(理论上)可以使用 Scala 宏之类的东西来做到这一点。如果这是您想要的,我建议您创建一个新问题。

于 2013-02-25T14:47:15.297 回答