2

このための命名法がすでにあるかどうかはわかりませんが、この質問のために、ピア実装またはネストされた実装という 2 つの用語を定義して、多くの親子エンティティ関係を含むデータ モデルにコレクション クラスを実装する方法を説明します。

ピアという用語を使用して、エンティティ クラスと一緒にモデル レイヤーにコレクション クラスを実装し、基本的に API でそれらをピアにするシナリオを説明します。

public class ParentEntity
{
  private ChildEntityCollection children;
}

public class ChildEntity
{
}

public class ChildEntityCollection : ICollection<ChildEntity>
{
}

ここでの主な利点は、たまたま同じ型の子を格納している他のエンティティ クラスでコレクション クラスを再利用できることです。

ネストされたという用語を使用して、次のようにネストされたクラスとして実装するシナリオを説明します。

public class ParentEntity
{
  private ChildEntityCollection children;

  public class ChildEntityCollection : ICollection<ChildEntity>
  {
  }
}

public class ChildEntity
{
}

ここでの主な利点は、各親が独自のコレクション クラスを実装して、その特定の親に最も最適化された方法で子を格納できることです。たとえば、ある親エンティティは配列データ構造が適切に機能することを発見し、別の親エンティティはスプレイ ツリーを使用する場合があります (よくわかりませんが、私の要点をよく示しています)。

Microsoft がさまざまな .NET 関連のフレームワークで両方のイディオムを使用していることに気付きました。System.Windows.Forms 名前空間は、入れ子になった実装に大きく依存しているようです。より多くの作業が必要ですが、私もこの方法を好む傾向があります。

推奨事項、コメント、代替案はありますか?

4

7 に答える 7

5

Microsoft が過去に何を行ったかに関係なく、現在の .NET API 設計ガイドラインでは、親クラスの外に表示される入れ子になったクラスの作成は推奨されていません。詳細については、 http://msdn.microsoft.com/en-us/library/ms229027.aspxを参照してください。

于 2009-10-15T16:51:50.557 に答える
2

もう 1 つのオプションは、コレクション クラスを子クラスにネストし、単に Collection という名前を付けることです。そうすれば、常に Child.Collection を名前として取得できます。

public class Child
{
  public class Collection : ICollection<Child>
  {
  }
}

public class Parent
{
  private Child.Collection children;
}
于 2009-10-15T16:38:17.747 に答える
1

私もピアアプローチを好みます。コレクションを親クラスの外で決して使用しない場合を除き、コレクションをネストする理由はありません(その場合は、ネストされたプライベート クラスにする必要があります)。

于 2009-10-15T16:55:23.170 に答える
1

ChildEntityCollection は本当に必要ですか? 提供されているコレクション型を使用しないのはなぜですか?

  //why bother?
//public class ChildEntityCollection : ICollection<ChildEntity>{}

public class ParentEntity
{
   //choose one
  private ChildEntity[] children;
  private List<ChildEntity> childrenInList;
  private HashSet<ChildEntity> childrenInHashSet;
  private Dictionary<int, ChildEntity> childrenInDictionary;
   // or if you want to make your own, make it generic
  private Balloon<ChildEntity> childrenInBalloon;
}
public class ChildEntity
{
}
于 2009-10-16T13:37:54.383 に答える
1

私は通常、特定のコレクション クラスを生成しないようにしています。特別なクラスが必要な場合もありますが、多くの場合、名前空間のようなジェネリック クラスを使用するだけCollection<T>で済みますReadOnlyCollection<T>System.Collection.ObjectModelこれにより、多くの入力が節約されます。すべてのコレクションは etc. から派生しIEnumerable<T>、LINQ と簡単に統合できます。要件に応じて、コレクションをICollection<T>または別のコレクション インターフェイスとして公開し、特定の要件を持つクラスが高度に最適化されたジェネリック コレクションを使用できるようにすることもできます。

public class ParentEntity {

  Collection<ChildEntity> children = new Collection<ChildEntity>();

  public Collection<ChildEntity> Children {
    get {
      return this.children;
    }
  }

}

IList<T>次のようにラップすることもできます。

public class ParentEntity {

  // This collection can be modified inside the class.
  List<ChildEntity> children = new List<ChildEntity>();

  ReadOnlyCollection<ChildEntity> readonlyChildren;

  public ReadOnlyCollection<ChildEntity> Children {
    get {
      return this.readOnlyChildren
        ?? (this.readOnlyChildren =
              new ReadOnlyCollection<ChildEntity>(this.children));
    }
  }

}
于 2009-10-16T13:43:07.523 に答える
1

個人的には、ピア実装の方が好きです。ネストされた実装では考えられないコードの再利用が促進されます。別のクラスが同じ要素のコレクションを格納する別の方法を実装する必要がある場合、コードの再利用を制限することなく、そのシナリオ用に別のクラスを簡単に実装できます。

ネストされた設定により、一部の開発者はコードを親クラスに密結合することにもなります。

于 2009-10-15T16:32:10.863 に答える
1

子エンティティを論理的に含めることができるエンティティがドメイン モデルに 1 つしかない場合にのみ、ネストされた配置を使用します。

たとえば、PieceOfMail クラスと MailPieces コレクション クラスがあるとします。

  class PieceOfMail { } 
  class MailPieces: Collection<PieceOfMail> { }

次に、ShipingCompany クラス、MailBox クラス、PostOffice クラス、MailRoute クラス、および MailManBag クラスはすべて、MailPieces として型指定された構成プロパティを持つことができるため、「ピア」手法を使用します。

しかし、同じドメイン内に、PostageDiscount のタイプを表すクラスと、出荷に適用される割引のセットを表すコレクション クラスがある場合、ShipmentTransaction クラスだけが論理的にコレクションを含むことができる場合があります。それらの割引のうち、ネストされた手法を使用します...

于 2009-10-15T17:07:49.530 に答える