对应的正确OO建模

时间:2009-05-22 07:10:59

标签: language-agnostic oop smalltalk

在我的编程中不断出现的东西,从某种观点来看,有两件事是相同的,但不同于另一件。比如,想象一下你建造了一个由火车连接的火车站图表,那么Vertex和RailStation这两个类别有时是相同的,有时则没有。

所以,想象一下,我的图表非常代表火车站和火车。然后我把这个图形移到另一个对象,删除一些顶点,然后我想要相应的火车站消失。

我不想让火车站成为顶点的“属性”,它们不是。此外,问题是对称的:如果我擦除铁路站,我希望相应的顶点消失。什么是建模或通信的正确OO方式。如果最终整体使用简单易行,我愿意通过编写一些支持方法或类来增加几英里。

我目前正在使用Smalltalk编程语言,但我认为这个问题并不是真正的小问题。我只是提到它,因为在Smalltalk中,你可以做一些很好的技巧,比如检查调用堆栈,这在这种情况下可能会有所帮助。

更新: 好吧,RailStations不是顶点!是吗?

好的,让我们考虑一下真实的代码,正如答案所要求的那样。让我模仿一个有孩子的人。那是最容易的事,对吧?孩子们也应该了解他们的父母,所以我们喜欢一棵双重联系的树。为了让儿童解散父母更容易,我将父母和孩子之间的联系模型建立为关系,父母和孩子的属性。

所以,我可以实现父>> removeChild:也许就像这样

removeChild: aChild
    (parent relationshipWith: aChild) disband.

因此,父母有一系列关系,而不是孩子。但每个关系对应给孩子。现在我想做这样的事情:

parent children removeAllSuchThat: [:e | e age < 12]

应该删除之间的关系。

在这里,关系和孩子在某种意义上是对应的。那么,我现在该怎么办?不要误会我的意思,我完全清楚我可以在不引入关系类的情况下解决问题。但事实上,父母和孩子确实分享了一种关系,那么为什么不对它进行建模并用它来帮助解散双重链接呢?

5 个答案:

答案 0 :(得分:3)

在您的问题域中,不是站点的一种顶点吗?在这种情况下,为什么不从顶点派生出站?

请注意使用短语“在您的问题域中”。您的问题似乎与使用图表中出现的火车站有关。所以是的,在那个领域,工作站是顶点。如果它是一个不同的问题领域,比如火车站架构的数据库,它们可能不是。大多数现代语言都支持一些命名空间的概念,以允许您在不同的域中拥有不同类型的具有相同名称的实体。

关于你的父母/孩子的问题,你再次过于笼统。如果我正在建模数学表达式和子表达式,如果我删除父项,我想删除并删除/释放所有子表达式。 OTOH,如果我在英国人口中建立法律责任关系,那么当责任被解散时(比如因为离婚),我只想删除这种关系,而不是删除/释放有自己独立存在的孩子。

答案 1 :(得分:2)

您似乎只想让RailStation继承Vertex(is-a relationship)。有关继承,请参阅此smalltalk tutorial。这样,如果你有一个RailStations图形,一个用于处理(通用)Vertexes图形的对象会自然地处理事情。

如果这种方法不起作用,则更具体(最好使用实际代码)。

答案 2 :(得分:2)

根据您对问题的描述,您将站点与顶点一一对应,删除站点应自动删除相应的顶点(反之亦然)。你还提到建立“火车站连接的火车站图”,你可以用它来表示一个图,其中车站是顶点,列车是边缘。

那么,一个站不是一个顶点的方式是什么?如果除了作为一个顶点之外,该站不存在,并且除了作为一个站之外不存在顶点,那么你将它们维护为两个不同但链接的实体有什么好处?

据我了解你的情况,station-isa-vertex和inheritance是建模的方法。

答案 3 :(得分:1)

拥有一个Relationship对象是个好主意。

我认为这里适当的问题是“应该使用它?”。

可能父类和子类正在扩展相同的Person超类,因此它们将具有一些共同的属性,例如年龄。

在我的想法中,我可以看到以下内容:父对象和子对象必须相互了解,因此两个类都必须保持指向同一关系的链接。 Relationship对象在单个父项和一定数量的子项之间保持一对多关系,并且它将保留对每个Person对象的引用。

通过这种方式,您可以在Relationshp对象中实现整个解散逻辑,或多或少地根据需要进行复杂化。您可以查询Relationship对象以了解该系列的哪些成员符合您的要求以执行某些操作。你可以安全地解散(和销毁)关系,因为它会知道所有成员,并会要求他们打破引用,然后就可以销毁,或者要求某些成员离开家人,保留关系对象活。

但这不是全部。关系应该是一个超类,由HierarchicalRelationship和PeerRelationship(或FriendRelationship)扩展。

此专业化允许您使用Parent(s)和Child(ren)以完全遍历的方式在其他层次结构之间进行链接。

这背后的真正概念是您的Relationship对象是以可伸缩和结构化的方式查询和组织整个Person对象(或Vertex对象)的关键,因此您最终使用的整个数据域可用于任何你喜欢的感觉,无论你是想解散群体还是走在他们之间的某条道路(或铁路)。

抱歉有大量的比喻。

答案 4 :(得分:1)

看看Fame,请参阅http://www.squeaksource.com/Fame.html

我们使用Collection的专用子类,在添加或删除元素时更新另一端。此外,您可以使用编译指示对类进行注释以注释关系。 Fame框架使用这些编译指示来完成所有类型的好东西。