建模相关对象

3
我正在设计一个应用程序,处理两组数据——用户和区域。这些数据是从第三方生成的文件中读取的。我有一个用户类和一个区域类,数据被读入到一个用户数组和一个区域数组中(或其他适当的内存结构,具体取决于我们采用的技术)。
这两个类都有一个唯一的ID成员,从文件中读取,而用户类包含一个区域ID数组,给出了一个关系,其中一个用户与多个区域相关联。
需求非常简单:
- 用户列表 - 区域列表 - 指定区域的用户列表 - 指定用户的区域列表
我的第一个想法是将数据保留在两个数组中,然后针对每个需求,有一个单独的方法,该方法将根据需要查询一个或两个数组。这很容易实现,但我并不确定它一定是最好的方式。
然后我想到,在用户类上有一个“获取区域”方法,在区域类上有一个“获取用户”成员,如果例如我处于一个区域对象的阶段,我可以通过一个属性找到它的用户,但是,区域类上的“获取用户”方法如何知道/访问用户数组呢?
我以前遇到过这个问题,但从来没有找到一个明确的解决方案。也许我只是把它搞得比实际上更复杂了。有人能提供任何提示、URL或书籍,帮助我解决这种设计问题吗?
更新: 感谢大家抽出时间留下一些提示。您的评论非常感激。
我同意这个问题的根源是多对多关系。我理解在关系数据库中如何建模,那很简单。
我收到的数据是来自第三方的二进制文件,因此我无法控制它们的结构,但当我读取它们时,可以以最佳方式存储它们。虽然这有点牵强附会,但我认为读入数据后将其存储在数据库中,程序将不得不查询数据库以获得结果。它并不是一大堆数据,所以我认为通过将其存储在内存结构中,可能会得到需要的结果。
7个回答

7

这真的是一个多对多的关系。

User <<--->> Area

将其分解为三个对象:用户(User)、区域(Area)和用户区域(UserArea)。
User: Id, name, etc.
Area: Id, name, etc.
UserArea: UserId, AreaId

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中的实现(没有回调函数)

这样做的优点是很容易返回一个迭代器来遍历Area并查找Members(反之亦然)

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

我认为第一种实现更符合LINQ的友好性。


类似于Steven A. Lowe的想法。我可以做类似的事情,它看起来像是我在关系数据库中拥有的模型,但是就对象而言,我认为可能有更好的方法让User的实例知道它关联的用户以及反之。 - Gavin

2

一个区域是否属于多个用户?如果是的话,它在技术上就是一对多关系。如果要将数据转换成关系数据库,你需要创建一个包含所有关系的表格。如果想使用数组进行操作,可以创建第三个数组。或者如果想以面向对象的方式进行操作,两个类都应该有指向相关区域/用户的指针数组。


这就是我想的,但我不是很确定。关于指针,我需要读取一个数组(或通用列表或其他内容),读取第二个数组,然后有一个第三个方法来填充每个指针数组? - Gavin

1

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

那么我的抱怨有什么好处呢?答案应该是与关系数据存储集成,而不是将其强行融入面向对象的范例中。这是经典的方块钉子,圆孔问题。


0
为什么不在涉及.NET的情况下使用带有关系的DataTables呢?如果涉及.NET,您可能还想了解泛型。

如果我在使用.NET,我会使用泛型列表而不是数组。然而,我并没有太多使用DataTable的经验。我会研究一下这个。 - Gavin

0
一种选择是针对最后两个需求使用字典。也就是说,一个 Dictionary<Area, List<User>> 和一个 Dictionary<User, List<Area>>。您可以在读取数据时构建它们。您甚至可以将一个类包装在这两个字典周围,并为每个需求在该类上拥有一个方法。这将使您能够确保字典保持同步。

0

同意dacracot的观点

还要看看DevExpress XPO


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接