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
{
}

这里的主要优点是每个父级都可以实现自己的集合类,以针对特定父级最优化的方式存储其子级。例如,一个父实体可能会发现数组数据结构运行良好,而另一个父实体可能会使用展开树(我知道这很模糊,但它很好地说明了我的观点)。

我注意到微软在各种 .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

另一种选择是将集合类嵌套在子类中,并将其命名为 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:32:10.863 回答
1

我也更喜欢对等方法。除非您永远不会在其父类之外使用它(在这种情况下,它应该是私有嵌套类),否则实际上没有理由嵌套集合。)

于 2009-10-15T16:55:23.170 回答
1

当域模型中只有一个实体可以在逻辑上包含子实体时,我只会使用嵌套排列。

例如,如果您有一个 PieceOfMail 类和一个 MailPieces 集合类

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

然后 ShipingCompany 类、MailBox 类、PostOffice 类、MailRoute 类和 MailManBag 类都可以具有类型为 MailPieces 的组成属性,所以我将使用“对等”技术。

但是,在同一个域中,如果您有一个表示 PostageDiscount 类型的类,以及一个表示要应用于装运的一组折扣的集合类,则可能只有 ShipmentTransaction 类可以在逻辑上包含一个集合在这些折扣中,我会使用嵌套技术......

于 2009-10-15T17:07:49.530 回答
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>和类等泛型类。这样可以节省很多打字。您所有的集合都来自etc.,并且很容易与 LINQ 集成。根据您的要求,您还可以将您的集合公开为或另一个集合接口,然后让具有特定要求的类使用高度优化的通用集合。ReadOnlyCollection<T>System.Collection.ObjectModelIEnumerable<T>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 回答