問題に多数の入力をロードし、それらの入力を処理して「問題空間」を作成する必要がある問題に取り組んでいます(つまり、入力への効率的なアクセスを可能にするデータ構造を構築するなど)。この初期化が完了すると、マルチスレッドプロセスが開始され、組織化/処理された入力が並行して広範囲に使用されます。
パフォーマンス上の理由から、並行フェーズですべての読み取り操作をロックして同期したくありません。私が本当に望んでいるのは、複数のリーダーが同時に安全にアクセスできる不変のオブジェクトです。
実用上の理由(読みやすさと保守性)のために、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フェーズ」の可変/不変オブジェクトのライフサイクルを、「かわいい」ことをあまり行わずに、可能な限り強制したいと思います。この目標を達成するためのより良い方法についてのコメントやフィードバックを探しています。これは珍しいユースケースではないと確信していますが、それをサポートするデザインパターンも見つかりません。
ありがとう。