3

在我的编程中不断出现一些东西,那就是从某些角度来看,两件事是相同的,但从另一个角度来看是不同的。就像,假设您构建了一个由火车连接的火车站图,那么 Vertex 和 RailStation 类有时是相同的,有时则不是。

所以,想象一下我有一个非常代表火车站和火车的图表。然后我将此图交给另一个对象,该对象删除了一些顶点,然后我希望相应的火车站消失。

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

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

更新:嗯,RailStations 不是顶点!他们是吗?

好的,让我们按照答案的要求考虑真实的代码。让我模拟一个有孩子的人。这是最简单的事情,对吧?孩子也应该知道他们的父母,所以我们就像一棵双环树。为了更容易从孩子中解散父母,我将父母和孩子之间的联系建模为关系,具有父母和孩子的属性。

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

removeChild: aChild
    (parent relationshipWith: aChild) disband.

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

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

这应该删除关系孩子。

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

4

5 回答 5

3

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

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

关于您的父母/孩子问题,您再次过于笼统。如果我正在对数学表达式和子表达式进行建模,如果我删除一个父项,我会想要删除并删除/释放所有子表达式。OTOH,ff我在英国人口中模拟法律责任关系,然后当责任解除(比如因为离婚)时,我只想删除这种关系,而不是删除/释放有自己独立存在的孩子.

于 2009-05-22T07:24:54.363 回答
2

根据您对问题的描述,您有站点与顶点的一一对应关系,删除站点应自动删除相应的顶点(反之亦然)。您还提到了构建“由火车连接的火车站图”,您显然是指一个图,其中车站是顶点,火车是边。

那么,车站在什么方面顶点呢?如果站只作为一个顶点不存在,并且如果一个顶点只作为一个站不存在,那么你认为将它们保持为两个不同但链接的实体有什么好处?

据我了解您的情况,station-isa-vertex 和继承是建模的方法。

于 2009-05-22T08:14:00.490 回答
2

似乎您只是希望 RailStation 从 Vertex 继承(是关系)。请参阅这个关于继承的smalltalk 教程。这样,如果您有 RailStations 图,则用于(通常)处理顶点图的对象将自然地处理事情。

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

于 2009-05-22T07:25:03.037 回答
1

拥有一个关系对象是个好主意。

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

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

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

通过这种方式,您可以在 Relationshp 对象中实现整个解散逻辑,或多或少如您所愿。您可以查询关系对象以了解哪些家庭成员符合您做某事的要求。您可以使关系安全地解散(和销毁),因为它会知道所有成员并要求他们破坏引用,然后它会准备好销毁,或要求某些成员离开家庭,保留关系对象活。

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

这种专业化使您可以让 Parent(s) 和 Child(ren) 以完全遍历的方式链接其他层次结构。

这背后的真正概念是,您的关系对象是以可扩展和结构化的方式查询和组织整个 Person 对象(或 Vertex 对象)的关键,因此您最终获得的整个数据域在任何意义上都是可用的比如,你是想解散团体还是在他们之间走一条特定的路径(或铁路)。

很抱歉有大量的隐喻。

于 2009-05-22T08:40:14.057 回答
1

看看名望,见http://www.squeaksource.com/Fame.html

当您添加或删除元素时,我们使用一个专门的子类Collection来更新另一端。此外,您可以使用 pragma 注释您的类以注释关系。Fame 框架使用这些 pragma 来做各种好事。

于 2009-06-03T11:54:20.297 回答