2

次の2つのデザインパターンから選択することがよくあります。

static {
    try {
        foo();
    }
    catch(Exception exc) {
        throw new RuntimeException(exc.getMessage());
    }
}

TheConstructor() throws SomeException {
    if(alreadyInited) {
        return;
    }
    alreadyInited = true;
    foo();
}

問題は、クラスごとに1回だけ初期化することです。つまり、静的に、ロガーの設定、ファイルからのマップのロードなどです。この操作が失敗した場合は、プログラムを停止する必要があります。 。これらのデザインパターンはどちらも扱いにくいように見えるので(最初のパターンの方が明らかにそうです)、これを行うためのより良い方法があるかどうか疑問に思います。

4

5 に答える 5

3

静的クラスコンストラクターの例外が適切なデザインパターンをエスケープできるようにしていますか?

いいえと思います。

まず、そのコンテキストでチェックされた例外をラップすることは、何かがうまくいかない場合、クラスの初期化に失敗することを意味します。

  • クラスのイニシャライザーから伝播する例外をキャッチして直接処理することはできません。

  • クラスの初期化中にキャッチされなかった例外は回復できません。例外をキャッチして処理できたとしても、クラスとそれに依存する他のすべてのクラスは、初期化できない状態のままになり、使用できなくなります。これは、(少なくとも)クラスローダー、場合によってはJVM全体にとって事実上「ゲームオーバー」です。

全体像は、これはおそらく静力学の不適切な使用を表しているということです。この問題を処理するためのより良い方法があります。例えば

  • クラスの初期化に依存するのではなく、(例外をキャッチして処理できる場所で)明示的な呼び出しを使用して初期化を実行します。

  • 静的(および場合によってはそれをラップするシングルトンクラス)を取り除き、依存性注入を使用します。

于 2012-05-16T22:15:27.350 に答える
1

ファクトリパターンはここで役立ちます。RunTime例外をスローすることはできますが、「CouldNotCreate」と呼ばれる例外を、何がうまくいかなかったかに関するいくつかのクールな情報とともにスローします。

于 2012-05-16T21:53:43.970 に答える
1

あなたの最初の例は私にはうまく見えます。あなたのクラスが絶対foo()に使えるようにする必要があるなら、それができないならfoo()、それは使えません。使用できない場合は、使用しないでください。静的初期化子から例外をスローすることは、クラスが使用されていないことを確認するための簡単で効果的な方法です。

残念ながら、Javaでは静的イニシャライザからチェックされた例外をスローすることはできません。なぜそうなのかわかりません。

于 2012-05-16T22:29:12.223 に答える
0

あなたはこのように2番目をもう少し厄介にすることができます:

static boolean isStaticInit = false;
static void staticInit() throws InitException {
    if (isStaticInit) return;

    // [init loggers, map, etc...throw InitException as appropriate]

    isStaticInit = true;
}

MyClass() throws InitException {
    staticInit();

    // ...
}

最初のオプションと2番目のオプションには微妙な違いがあることに注意してください。最初のオプションではstatic{}、クラスが最初にロードされたときにブロックが呼び出されますが、2番目のオプションでは、最初のクラスインスタンスが構築されるまでinitコードは呼び出されません。たとえば、を呼び出すコードがある場合、これは違いを生む可能性がありますMyClass.myStaticMethod()。オプション1を使用すると、呼び出しによってクラスの初期化がトリガーされます。オプション2では、そうではありません。

于 2012-05-16T22:09:43.160 に答える
0

この場合、「構成」にシングルトンパターンを選択します。

しかし、コンストラクター内のロジックは非常に奇妙で、静的ブロックはよりクリーンなIMHOですが、テストするのは簡単ではないと思います。気をつけて。

于 2012-05-16T21:55:28.280 に答える