为什么Swing组件有.getParent()方法,这是否违反了面向对象原则?

3
我正在研究面向对象设计原则和启发式方法。在Arthur J. Riel(1996)的著作《面向对象设计启发式》中,我看到了这个启发式:启发式4.13:一个类必须知道它包含什么,但它不应该知道谁包含它。J.Reil认为,这样做的主要原因是可重用性。
但在Swing结构中,我们可以直接访问父对象的引用。
例如:label.getParent() 所以我的问题是:
为什么Swing组件有.getParent()方法?
哪些面向对象原则或启发式背后存在这种方法?

2
这个启发式方法是否被广泛认可还不清楚。 - Oliver Charlesworth
父元素和子元素之间存在循环依赖关系。这也可能是代码异味,我们应该使用类似“桥接”对象来访问父级。 - Gholamali Irani
这取决于你所说的“依赖性”的含义。如果你想从子级导航到父级,你需要在某个地方有一个边缘。你可以通过使用“组件”接口或类似方法来避免类型依赖。 - Oliver Charlesworth
那么,双向链表也是一个不好的选择吗? - MadProgrammer
不,这只是一种结构性工具,如果你想在任何情况下使用它,你应该遵循上下文的原则。 - Gholamali Irani
2个回答

7
这里有两件事情:在软件工程中,没有一成不变的规则。始终需要平衡竞争的不同方面。
接下来:UI组件的主要目的是(惊喜)用于UI。通常任何UI元素都属于一个父元素。您不能在两个窗口中显示相同的表格(也许是相同的数据,但不是UI表格对象!)。从那里开始:经常需要找到UI组件的父级。 UI元素始终是所属的 - 当您可以轻松上下移动时,更加方便。
长话短说:我认为你正在看一个非常特殊的情况 - 在这种情况下,偏离某本书中的规则是很有意义的。

非常感谢,我明白你的意思。我无法在课堂上解释这个违规行为。然而,我坚持认为这个启发式在任何其他系统中都是正确的(除了UI Degin)。 - Gholamali Irani

1
免责声明:我没有阅读所涉及的书籍,因此我只能推测作者的意图。
但我的猜测是,这里的意图是该类不应基于包含它的类的类型而改变其行为。因此,当一个按钮在滚动窗格中时,它不应该与它在JPanel或JFrame中的行为有所不同。
但UI组件的层次结构是它们职责的一部分。它们处于树形结构中,因此它们不仅维护彼此之间的链接,而且具有访问器以允许客户端代码导航该结构。现在,你可以有一个结构,只有父节点链接到子节点,反之亦然,就像你可以有一个单链表。但是拥有双向链接列表,每个节点不仅有指向后面节点的指针,还有指向前面节点的指针,并不违反面向对象的原则,拥有双向链接树结构,其中子节点也有指针,允许从子节点向上导航到父节点,也不违反面向对象的原则。
我们必须问自己,知道谁包含它会如何影响可重用性?为什么知道这一点会使类 less reusable?现在,如果它基于包含它的对象改变其行为,那就会这样做。你不能只是拿起这个类并在其他地方使用它,因为它可能不会做你期望它做的事情。但仅仅维护链接并不会损害可重用性。
(我要注意的是,如果您要从层次结构中添加和删除组件,则必须在其API中小心处理,以便当您告诉其中一个组件您正在断开链接时,它们两个都可以更新其状态。但是,这可以作为API设计的一部分来处理。只要在第一个版本中提前完成了这项工作,以便所有编写为该组件层次结构的一部分的类的合同中都包含了这一点,它就不会成为问题。)

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