5

問題に多数の入力をロードし、それらの入力を処理して「問題空間」を作成する必要がある問題に取り組んでいます(つまり、入力への効率的なアクセスを可能にするデータ構造を構築するなど)。この初期化が完了すると、マルチスレッドプロセスが開始され、組織化/処理された入力が並行して広範囲に使用されます。

パフォーマンス上の理由から、並行フェーズですべての読み取り操作をロックして同期したくありません。私が本当に望んでいるのは、複数のリーダーが同時に安全にアクセスできる不変のオブジェクトです。

実用上の理由(読みやすさと保守性)のために、InputManagerを真の不変オブジェクト(つまり、すべてのフィールドが「最終」であり、構築時に初期化される)にしたくありません。InputManagerには多数のデータ構造(リストとマップ)があり、それぞれのオブジェクトには相互に多くの循環参照があります。これらのオブジェクトは、「真の」不変オブジェクトとして構築されます。InputManagerに14引数のコンストラクターは必要ありませんが、構築された問題空間の一貫した読み取り専用ビューを提供するには、InputManagerクラスが必要です。

ここでEricLippertが説明しているように、私が目指しているのは「アイスキャンディーの不変性」です。

私が採用しているアプローチは、すべての変更メソッドの「パッケージの可視性」を使用し、単一のパッケージ内ですべての変更可能なアクション(つまり、InputManagerの構築)を実行することに依存しています。ゲッターはすべて一般公開されています。

何かのようなもの:

public final class InputManager {  // final to prevent making mutable subclasses 
    InputManager() { ... } //package visibility limits who can create one
        HashMap<String,InputA> lookupTable1;
        ...

    mutatingMethodA(InputA[] inputA) { //default (package visibility)
        //setting up data structures...
    }

    mutatingMethodB(InputB[] inputB) { //default (package visibility)
        //setting up data structures...
    }

    public InputA getSpecificInput(String param1) {
        ... //access data structures
        return objA; //return immutable object
    }
}

全体的な考え方は、私が十分に明確になっていない場合、単一のスレッドでInputManagerを構築し、それをオブジェクトを使用して同時作業を行う複数のスレッドに渡すことです。この「2フェーズ」の可変/不変オブジェクトのライフサイクルを、「かわいい」ことをあまり行わずに、可能な限り強制したいと思います。この目標を達成するためのより良い方法についてのコメントやフィードバックを探しています。これは珍しいユースケースではないと確信していますが、それをサポートするデザインパターンも見つかりません。

ありがとう。

4

3 に答える 3

1

2 つのフェーズに別々のインターフェイスを使用するだけでよいと思います。1 つは構築部分用、もう 1 つは読み取り部分用です。このようにして、アクセス パターンをきれいに分離します。これは、インターフェイス分離の原則 (pdf)のインスタンスとして見ることができます。

クライアントは、使用しないインターフェースに依存することを強いられるべきではありません。

于 2012-10-24T18:20:36.250 に答える
1

オブジェクトが安全に公開され、リーダーがオブジェクトを変更できない限り。

ここでの「公開」とは、作成者がオブジェクトを読者に提供する方法を意味します。たとえば、作成者はそれをブロッキング キューに入れ、リーダーはキューをポーリングしています。

公開方法によって異なります。安全なものだとおもいます。

于 2012-10-24T18:34:58.477 に答える
1

個人的には、あなたのシンプルで十分なアプローチにとどまりますが、興味がある場合は、変更可能なコンパニオンイディオムのようなものがあります。包含インスタンスのすべてのフィールドとゲッターを再利用しながら、ミューテーターを持つ内部クラスを作成します。

ミュータブルなコンパニオンを失うとすぐに、コンパニオンが残した外側のインスタンスは真に不変になります。

于 2012-10-24T19:05:07.090 に答える