2010-11-08 43 views
2

在设计相对较大的系统时,我对OOD感到非常困惑。总是,我们谈论两个实体之间的关系。我的问题是关于哪一个拥有另一个?面向对象的设计,定义关系

  1. 在设计停车场时,有许多停车位。汽车是否应该有一个称为停车位的数据字段,或者停车位是否应该放置汽车?或两者?

  2. 在图书馆预订系统中,我假设有一个类库,一个类书和一个类用户。应该让用户打电话结帐(预订),还是书本电话结帐(用户),或图书馆电话结账(书籍,用户)?

这对我来说非常困惑。欢迎任何评论/建议。

百合

回答

2

这取决于具体情况以及“自己”的含义。

在您的第一个示例中,汽车和停车位之间存在一对一的关系。从数据库的角度来看,你将不得不判断哪个应该“拥有”另一个(哪个表'拥有'外键)。你会根据预期的使用情况作出判断 - 例如 - 由于停车位可能会保持不变,但你有汽车一直来来往往,停车场“拥有”汽车可能更符合逻辑。这就是你的设计技巧发挥作用的地方。

在第二个例子中,在我看来,一本书只能一次签出给一个用户,而“签出”是出现在书上的一个操作。因此正确的解决方案是Book.checkout(user)。在此基础上,用户可能一次结帐多个图书,因此我倾向于在图书馆中使用结帐方法,因此Library.checkout(Books[], user)依次调用Book.checkout(user)

1

#1,停车位应该保持它是否被占用的记录,如果有,是什么在它的车。否则,看看你是否可以停放在某个地方,你将不得不查询每辆车,看看他们是否在那个地方。

我对#2的直接思考是,它应该是Library.checkout(Book, User),这样你记下一个用户已经签出了一本特定的书。

这很大程度上取决于您正在尝试做的事情,您应该以最容易解决问题的方式进行设计。

有时在两个地方复制数据并不是一个可怕的想法,只要保持它的同步。例如,如果您需要知道特定汽车停放的位置,您最终还是希望跟踪Car课程中的数据,否则您将不得不轮询每个停车位以了解如果那辆车停在那里。

+0

当然是:librarian.checkout(书,用户)? – 2010-11-08 07:15:46

+0

@WW,你的意思是库包含一个库管理员列表,理想情况下,操作应该在库级别进行,Library.checkout(Book,User)可以调用Libarian.checkout(Book,User); – Lily 2010-11-08 17:44:08

0

在面向对象的设计中,对象可以被认为是一个实体。此时,您可以使用实体关系建模来更好地了解谁拥有什么。

当你设计你的模型时,你不应该在意你将如何实现它。我的意思是你不应该认为谁将拥有什么,因为这是设计的另一个过程,当你要将你的模型转换为对象时(可以是数据表,XML,C#对象......)。):只有在这一点上反对实体得到的关系,你才能决定谁必须拥有什么(有时候甚至违背了要求,因为我稍后会向你展示)。 在设计时你必须专注于你的要求。在汽车和停车场的情况下,您应该考虑:

有多少公园车可以占用?

一个公园可以容纳多少辆汽车?

我的系统回答什么样的答案?例如:作为用户,我想知道汽车停在哪里的车牌号码(在这种情况下,以前的答案是错误的,因为如果您让公园拥有汽车,您应该在公园中循环以获取汽车的位置)

正如你所看到的,它确实取决于你的业务需求,特别是当你有“一对一”关系时(如本例)。

所以我可以建议你看看“实体关系建模”,并坚持其概念,以更好地设计你的对象模型。

0
  1. 在这种情况下,无疑停车位应持有的车(这就是所谓的聚合),因为汽车和停车位之间的关系是不是永久性的(不同的汽车可以在同一个停车的地方停放在同一天)

  2. 在这种情况下,我想用户想要一本书,所以这个系统的GUI必须有一些按钮(或者smht else),用户必须单击以保留一本书。因此,用户调用系统的方法checkout(book)(对象库代表它)来检查书籍是否空闲(或可用)。然后系统(库)检查该书是否未被其他用户预先保留,因此它为本书的所有实例调用方法Book.check()。在这种解决方案中,系统中的每个用户帐户都应该有一个使用Book.check()方法的预订书籍列表。

0

想出盒子,我不认为你提供的例子有一种天然的“有”或“拥有”的关系,并有更多的关系比“具有”或“拥有”。在我看来,我想用一个松散耦合的关系作为例子,从实现的角度来看,我会用地图来描述和维护这种关系,这意味着,对于停车场和汽车,我会放置一张地图在Parking类中,并将其插槽映射到汽车,如果我们在地图中找到插槽,则我们知道该插槽已被占用,如果没有,则它是空闲插槽,对我而言,说汽车没有多大意义拥有插槽或插槽拥有汽车;对于图书馆的例子来说,同样的事情,这本书和借阅者之间的关系非常松散,我会在图书馆课上放一张地图,然后将这本书映射到借阅者身上。那个人真的做了结帐行动?它既可以是图书馆工作人员也可以是自动机器,或者简单地说就是图书馆,所以我们可以拥有一个library.checkout(用户,书籍),并在这个方法内部将书籍和用户放入地图。

对于奖金,什么是真正的“有”的关系情景?不是一个人有车,这不是真的是“有”,即使我们在句子中“有一个”(不要让人类的语言误导你),这只是意味着,在汽车的班级里,有一个名为ownerName或ownerId的字符串字段,就是这样。一个真实的“有一个”关系场景的例子是人类有一颗心或一辆汽车有一个引擎,这意味着在实施过程中,人类中真正存在一个心脏类字段。

面向对象的设计有多漂亮!