建模相关对象

时间:2008-09-30 15:54:32

标签: oop class-design

我正在设计一个处理两组数据的应用程序 - 用户和区域。从第三方生成的文件中读取数据。我有一个User类和一个Area类,数据被读入Users数组和Areas数组(或其他适当的内存结构,具体取决于我们使用的技术)。

这两个类都有一个唯一的ID成员,该成员从文件中读取,而User类包含一个Area ID数组,给出了一个用户与许多区域相关联的关系。

要求非常简单:

  • 用户列表
  • 区域列表
  • 指定区域的用户列表
  • 指定用户的区域列表

我的第一个想法是将数据留在两个数组中,然后对于每个要求,都有一个单独的方法,可以根据需要询问一个或两个数组。这很容易实现,但我不相信它一定是最好的方式。

然后我想到在User类上有一个'Get Areas'方法,在Area类上有一个'Get Users'成员,如果我在一个我有一个Area对象的阶段会更有用,我可以通过属性找到它的用户,但那么Area类上的'Get Users'方法如何知道/可以访问Users数组。

我以前曾多次遇到这个问题,但从未真正想出过一个明确的解决方案。也许我只是让它变得比实际更复杂。任何人都可以提供任何有助于我进行此类设计的提示,网址或书籍吗?

更新: 谢谢大家花时间留下一些提示。非常感谢您的评论。

我同意这个问题的根源是多对多的关系。我理解如何在关系数据库中建模,这非常简单。

我收到的数据是来自第三方的二进制文件形式,所以我无法控制这些数据的结构,但我可以将它以最好的方式存储在我阅读时。它有点方形在圆孔中钉,但我想在将其存储在数据库中时将其读取,程序将不得不查询数据库以获得结果。这不是大量的数据,所以我认为通过将其存储在内存结构中可以得到我需要的东西。

7 个答案:

答案 0 :(得分:7)

这实际上是一种多对多的关系,

User <<--->> Area

将其分为3个对象,User,Area和UserArea:

User: Id, name, etc.
Area: Id, name, etc.
UserArea: UserId, AreaId

答案 1 :(得分:3)

非常基本,但想法是:

struct/class Membership
{
   int MemberID;
   int userID;
   int areaID;
}

此类实现“用户所属区域”成员资格概念。 将其中一个粘贴到集合中的每个成员资格中,并查询该集合以查找满足您要求的子集。

编辑:另一种选择

您可以在每个会员中存储区域列表,并在每个区域中存储会员列表。

区域中的

public bool addMember(Member m)
{
   if (/*eligibility Requirements*/)
   {
      memberList.add(m);
      m.addArea(this);
      return true;
   }
   return false;
}

和Member中的类似实现(没有回调)

这样做的好处是可以很容易地返回迭代器来遍历区域并找到成员(反之亦然)

缺点是它非常紧密耦合,这可能会导致未来的问题。

我认为第一个实现更符合LINQ。

答案 2 :(得分:2)

某个区域属于多个用户吗?如果是的话,这在技术上是多对多的关系。如果要将数据转换为关系数据库,则需要创建包含所有关系的表。我想如果你想使用数组,你可以创建第三个数组。或者,如果您确实希望以OO方式执行此操作,则两个类都应具有指向关联区域/用户的指针数组。

答案 3 :(得分:1)

对不起,这不是面向对象的问题。这是一个关系问题。因此所有对基数的引用(多对多)。这是关系数据库建模101.我并不是要批评Gavin,只是指出一个新的视角。

所以我的咆哮有多好。答案应该是与关系数据存储集成,而不是将其强加到面向对象的范例中。这是经典的方形钉,圆孔问题。

答案 4 :(得分:0)

如果涉及.NET,为什么不将DataTable与关系一起使用?如果涉及到.NET,您可能也想查看泛型。

答案 5 :(得分:0)

一种选择是为最后两个要求中的每一个使用字典。也就是说,Dictionary<Area, List<User>>Dictionary<User, List<Area>>。您可以在读取数据时构建它们。你甚至可以围绕这两个词典包装一个类,并且只针对每个需求在该类上有一个方法。这样可以确保字典保持同步。

答案 6 :(得分:0)

同意dacracot

另请参阅DevExpress XPO