複雑なオブジェクトツリーを構築しています。 A
、B
、C
、D
、およびE
の合計5つのタイプがあります。ルートノードであるA
のインスタンスが1つあります。 A
には1つ以上のB
sが子としてあり、各B
には1つ以上のC
sが子としてあります。元のデータ形式は、5つの数値(A
、B
、C
、D
、およびE
の数値ID)とそれぞれに関連付けられるメタデータで構成されるストリームです。
ツリーにある程度のフィルタリングを追加しようとしています。私の現在のアプローチは、入力を取得してA
のコンストラクターに渡し、それをB
コンストラクトのA
sとC
コンストラクトのB
sにフローダウンすることです。ただし、フィルタリングは最終的にE
のレベルで行われます。特定のE
のすべてのD
が存在しない場合、そのD
を作成したくありません。 C
にD
sがない場合、そのC
を存在させたくありません。
私の最初の考えは例外をスローすることですが、それはフロー制御に例外を使用しているようです。一部の言語は例外を優先しますが、私は現在Javaで作業しており、例外は例外的な条件になる傾向があります。フィルタが一致しないことは例外的なケースではないと思います。
最終ツリーに子を持つノードのみが含まれ、フィルターが適用されるようにするためのオプションは何ですか?
これを行うには、データ構造の各レベルでMap<Id, Container>
を使用します。コンテナがすでに存在する場合はコンテナを返す、またはまだ存在しない場合は新しいContainer
を作成するプライベートヘルパーメソッドを記述します。 これは一般にgetOrAdd
と呼ばれるメソッドです。
いつものように、基礎となるコンテナがまだ存在していることを確認することは、これを間違えると繰り返しコピーペーストする危険があるボイラープレートコードの束です。代わりに、これを行うために独自のデータ構造を作成する必要があります。または、Guavaを使用して、 Multimap
(データの場合に使用できる)を含む多くの便利なツールを提供することができます。構造はかなりばかげています)および ForwardingMap
(これにより、すべてのレベルにメタデータがある場合、独自のMap実装を簡単に作成できます)。次に、コンテナがまだ存在しない場合はget
と記述して、 Supplier
/Factory
(Guavaを使用していない場合)を使用するか、もしそうなら、既存のもの。
まず、コンストラクターで複雑なオブジェクトを作成することは必ずしも良い考えではないことを指摘します。
そうは言っても、それが現在のコードの動作方法であり、それを変更したくない場合は、コンストラクターを軽量ファクトリと交換できるはずです。
A()新しいC()を実行し、それが本当に必要でないと判断する代わりに、ファクトリまたは静的メソッドを使用して実行できます、言語によって異なります):A() C#get()を呼び出すと、Cまたはnullがフィルターで除外された場合に返されます。