web-dev-qa-db-ja.com

オブジェクトのリストを持つオブジェクトのリストを持つオブジェクトを作成するためのデザインパターン

良いOOP=設計の観点から、オブジェクトのリストのコンテナーであり、他のコンテナーであるオブジェクトの別のリストを含むだけのコードを構築するための最良の方法は何ですか?

例:クックブックは、道順のリストを所有するレシピのリストを所有する章のリストを所有します。各オブジェクトは、全体の中の異なるレイヤーです。わかりやすくするため、Wordの「リスト」を使用して、複数のオブジェクトを格納するために使用されるすべてのデータ構造を参照しています。

ネストされたオブジェクトの内部にネストされたオブジェクトのこのロシアの人形の問題に何度も遭遇しました。ネスト階層を介して最下位レベルのオブジェクトを渡してみました。また、最下位のネストされたオブジェクトに情報を渡すメソッドを記述しようとしました。中間クラスには、オブジェクトまたは情報を渡す以外に何もしないメソッドが含まれているため、私の構造は常に乱雑に感じられます。

コメントに混乱が生じたことによる追加:一般的なタイプの問題を処理するために研究すべきことの方向性を探しています。私が目の前にある特定のコーディングの問題の解決策を求めているのではありません。 「すべてを統治する答えは1つ」とは期待していませんでしたが、「Xの状況にはAのデザインパターンを使用し、Yの状況にはBのデザインパターンを使用し、Zに注意してください。」この例は、特定のコンテキストではなく、一般的なコンテキストを提供するためのものです。

8
WP0987

簡単にする1つの方法は、すべてのクラスが同じインターフェースを実装するので、区別なく扱うことができるということです。あります これの既知のパターン

enter image description here

これはツリーを作成するので、良いニュースです。次に、外部管理クラスで、項目を検索するための再帰的なメソッドを記述できます。

たとえば、メソッドfindAndAdd(String tagToFind, Component componentToAdd);を書くことができます

パターンで文書化されている基本インターフェイスに、tagMatches(String tag)とすべての一般的なゲッターとセッターを追加して、クラスと区別されないように項目を処理できるようにする必要があります。

hasChild()およびnextChild()メソッドを追加して、反復を実装します。

2

シンプルでバカにしてください!

あなたの例では、Cookbooksを含み、Chaptersを含み、Recipesを所有するDirectionsをモデル化したいと考えています。良いOO設計の観点から、これを正確にモデル化します:Cookbookの集約リストを持つクラスChaptersRecipesの集約リストを持ち、それぞれにDirectionsのリストがあります。これは、「現実世界のオブジェクト」から「OOPオブジェクト」への簡単なマッピングです。これは、オブジェクト指向モデリングのコアアイデアの1つです。あなたとこのデータを処理する必要がある人のために維持します。

この時点では、コードはまだ乱雑ではありません。次のようなメソッドを頻繁に記述する必要がある場合は、面倒になる可能性があります。

 // inside a Cookbook method:
 foreach chapter in listChapters
     foreach recipe in  chapter.listRecipes
          foreach  direction in  recipe.listDirection
              // do something with direction                

プログラミング言語が独自のイテレーター関数(C#やPythonなど)の作成を十分にサポートしている場合は、このようなコードを複数回記述することを回避できます。そうすれば、クックブックのすべての方向などを取得するために、再利用可能なヘルパー関数を1回簡単に提供できます。 ビジターパターン を利用する別のアプローチでは、その階層内のすべてのオブジェクトを「訪問」するさまざまな操作を提供し、訪問中に「何か」を実行できます。

もちろん、uniformコンテナーがある場合、階層の各レベルでコンテナーは同じタイプのコンテナーのリストを保持できます、@TulainsCórdovaの回答で提案されている複合パターンは理にかなっています。これの例は、ファイル/フォルダー階層、または抽象構文ツリーのツリー構造で、式には部分式を含む部分式が含まれます。ただし、この例では、各レベルで記述した各コンテナオブジェクトは別のレベルの各オブジェクトとは異なり、名前が異なり、動作も異なり、特定のタイプのサブコンテナのみが含まれます。したがって、説明したケースを複合パターンにシューホーンしようとすると、コードが本当に厄介になります。

16
Doc Brown