有一件事情在我的编程中经常出现,那就是两个东西在某种角度上是相同的,但从另一个角度来看却是不同的。比如说,假设你建立了一个由火车站通过火车连接起来的图形,那么类Vertex和RailStation有时候是相同的,而有时候又不同。
所以,假设我有一个非常代表火车站和火车的图形。然后我把这个图形交给另一个对象,它删除了一些顶点,然后我想让相应的铁路站消失。
我不想将铁路站作为顶点的“属性”,因为它们并不是。此外,问题是对称的:如果我删除了一个铁路站,我希望相应的顶点也消失。那么,面向对象的正确建模或者对应方式是什么呢?如果最终的使用方法简单易懂,我愿意写一些支持方法或者类来实现。
我目前正在使用Smalltalk编程语言,但我认为这个问题并不是特定于Smalltalk的。我提到它只是因为在Smalltalk中,你可以像检查调用堆栈一样做一些很酷的技巧,这可能在这种情况下有所帮助。
更新: 好吧,RailStations并不是Vertices!它们是吗?
好的,让我们考虑真正的代码,就像答案中要求的那样。让我用一个孩子和父母的例子来模拟。这应该是最简单的事情,对吧?孩子也应该知道他们的父母,所以我们有一个双向链接的树形结构。为了更容易地解除父母与孩子之间的联系,我将父母与孩子之间的链接建模为一种关系,并具有父母和孩子两个属性。
因此,我可以像这样实现parent>>removeChild:
因此,一个父级对象具有关系的集合,而不是子代。但是每个关系对应着一个子代。现在我想要做这些事情:
所以,假设我有一个非常代表火车站和火车的图形。然后我把这个图形交给另一个对象,它删除了一些顶点,然后我想让相应的铁路站消失。
我不想将铁路站作为顶点的“属性”,因为它们并不是。此外,问题是对称的:如果我删除了一个铁路站,我希望相应的顶点也消失。那么,面向对象的正确建模或者对应方式是什么呢?如果最终的使用方法简单易懂,我愿意写一些支持方法或者类来实现。
我目前正在使用Smalltalk编程语言,但我认为这个问题并不是特定于Smalltalk的。我提到它只是因为在Smalltalk中,你可以像检查调用堆栈一样做一些很酷的技巧,这可能在这种情况下有所帮助。
更新: 好吧,RailStations并不是Vertices!它们是吗?
好的,让我们考虑真正的代码,就像答案中要求的那样。让我用一个孩子和父母的例子来模拟。这应该是最简单的事情,对吧?孩子也应该知道他们的父母,所以我们有一个双向链接的树形结构。为了更容易地解除父母与孩子之间的联系,我将父母与孩子之间的链接建模为一种关系,并具有父母和孩子两个属性。
因此,我可以像这样实现parent>>removeChild:
removeChild: aChild
(parent relationshipWith: aChild) disband.
因此,一个父级对象具有关系的集合,而不是子代。但是每个关系对应着一个子代。现在我想要做这些事情:
parent children removeAllSuchThat: [:e | e age < 12]
这应该删除关系和子元素。
在这里,关系和子元素在某种程度上是对应的。那么,我现在该怎么办?别误解我的意思,我完全知道我可以不引入关系类就解决问题。但事实上,父母和子代确实分享一种关系,为什么不对其进行建模,并将其用于帮助较不强制性地解散双链接呢?