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

Why Swing Components have .getParent() method, Is it violated Object Oriented Principles?

我正在研究面向对象的设计原则和启发式方法。
在 Arthur J. Riel(1996 年)的《面向对象的设计启发式》一书中,我看到了这个启发式:

Heuristic 4.13: A class 必须知道它包含什么,但它不应该知道谁包含它。 基于J.Reil,主要原因是可重用性。

但是在Swing Structure中,我们可以直接访问Parent对象的引用。

例如:label.getParent()

所以我的问题是:
为什么 swing 组件有 .getParent() 方法?
哪些面向对象原理启发式隐藏了现有的这种方法?

这里有两点:在软件工程中没有规则是一成不变的。它始终是关于平衡具有某种竞争力的不同方面。

那么:UI 组件的主要目的是(惊喜)在 UI 中使用。通常任何 UI 元素只属于一个父元素。您不能在两个 windows 中出现相同的 table(可能是相同的数据,但 UI table 对象不是!)。从那里开始:到达 UI 组件的父级是您一直需要的。 UI 元素总是拥有的——当你可以轻松地上下移动时,它会更方便。

长话短说:我认为您在这里看到的是一个非常特殊的情况 - 偏离某本书中规定的规则很有意义。

免责声明:我没有读过这本书,所以我只能推测作者的意思。

但我的猜测是,这里的目的是 class 不应 根据 类型[=29] 改变其行为 =] 包含它的 class。因此,ButtonScrollPane 中的行为不得与在 JPanelJFrame 中的行为不同。

但是 UI 中组件的 层次结构 是他们职责的一部分。它们处于树形结构中,因此它们不仅相互维护 link,而且它们具有允许客户端代码导航该结构的访问器。现在,你可以有一个结构,其中只有 parents 有 links 到 children,反之亦然,就像你可以有一个 singly-linked 列表一样。但是要有一个 doubly-linked 列表,其中每个节点都有一个指针,不仅是它后面的节点,还有一个指向它前面的节点的指针,并不违反 object-oriented 原则,并且拥有 doubly-linked 树结构也不是违规行为,其中 child 节点也有允许导航 up 树的指针,从 children至 parents.

我们必须自问, 知道谁包含它会如何影响可重用性?为什么知道这会降低 class 的可重用性?现在,如果它根据包含它的人改变它的行为,那就可以了。您不能只使用 class 并在其他地方使用它,因为它可能不会执行您期望的操作。但是仅仅维护 links 不会损害可重用性。

(我会注意到,如果您要在层次结构中添加和删除组件,则必须小心处理它们 API 以便当您告诉其中一个您切断 link,它们都可以更新它们的状态。但这可以作为 API 设计的一部分来处理。只要在第一个版本中预先完成,它就是所有 class 编写为该组件层次结构的一部分的 es 的合同,它不会造成问题。)