-1

まず、私はScalaを使用していますが、どのJavaアプローチでも機能します。(理解しやすいように、例としてJavaコードを使用します。)

私がConnectionインターフェースとその実装RealConnectionを持っているとしましょうFakeConnection

アプリケーションにリリースエントリとテストエントリの2つのエントリが必要です。通常どおりにアプリケーションをコーディングし、リリースバージョンが使用するすべてのクラスを使用するテストを開始しますが、のFakeConnection代わりに使用する1つの例外があり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 に答える