Java 为什么Swing组件有.getParent()方法,它违反了面向对象的原则吗?

Java 为什么Swing组件有.getParent()方法,它违反了面向对象的原则吗?,java,swing,oop,software-design,object-oriented-analysis,Java,Swing,Oop,Software Design,Object Oriented Analysis,我正在研究面向对象的设计原则和启发法 在Arthur J.Riel(1996)的著名著作《面向对象设计启发法》中,我看到了这种启发法: 启发式4.13:一个类必须知道它包含什么,但它永远不应该知道谁包含它。 基于J.Reil,主要原因是可重用性 但在Swing结构中,我们可以直接访问父对象的引用 例如:label.getParent() 所以我的问题是: 为什么swing组件有.getParent()方法 哪些面向对象的原则或启发式是现有这种方法所不具备的?这里有两件事:在软件工程中没有一成不变

我正在研究面向对象的设计原则和启发法
在Arthur J.Riel(1996)的著名著作《面向对象设计启发法》中,我看到了这种启发法:

启发式4.13:一个类必须知道它包含什么,但它永远不应该知道谁包含它。 基于J.Reil,主要原因是可重用性

但在Swing结构中,我们可以直接访问父对象的引用

例如:
label.getParent()

所以我的问题是:
为什么swing组件有.getParent()方法

哪些面向对象的原则启发式是现有这种方法所不具备的?

这里有两件事:在软件工程中没有一成不变的规则。它总是关于平衡不同方面的竞争

然后:UI组件的主要用途是(惊喜)在UI中使用。通常,任何UI元素都只属于一个父元素。不能在两个窗口中显示相同的表(可能是相同的数据,但不是UI表对象!)。从这里开始:访问UI组件的父级是您一直需要的。UI元素总是被拥有的——当你可以轻松地上下移动时,它会更加方便


长话短说:我想你现在看到的是一个非常特殊的案例——在这个案例中,偏离某本书中的规则是很有意义的

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

但我的猜测是,这里的意图是,类不应基于包含它的类的类型来更改其行为。因此,
按钮
滚动窗格
中的行为不得与在
JPanel
JFrame
中的行为有所不同

但是UI中组件的层次结构是其职责的一部分。它们位于树结构中,因此它们不仅维护彼此之间的链接,而且还具有允许客户端代码浏览该结构的访问器。现在,你可以有一个只有父母链接到孩子的结构,反之亦然,就像你可以有一个单链表一样。但是,拥有一个双链接列表,其中每个节点都有一个指针,不仅是它后面的节点,而且还有一个指向它前面的节点的指针,这并不违反面向对象原则,而且拥有一个双链接树结构,其中子节点也有允许在树上导航的指针,这也不违反面向对象原则,从孩子到父母

我们必须扪心自问,知道谁包含它会影响可重用性吗?为什么知道这一点会降低类的可重用性?现在,如果它根据谁控制了它而改变它的行为,那就行了。你不能把这门课带到别的地方去用,因为它可能做不到你期望它做的事情。但是仅仅维护链接并不会损害可重用性


(我注意到,如果要从层次结构中添加和删除组件,则必须在API中采取一些谨慎措施,这样当您告诉其中一个用户正在切断链接时,它们都可以更新它们的状态。但是,这可以作为API设计的一部分来处理。对于作为组件层次结构一部分而编写的所有类的契约,这不会造成问题。)

不清楚这种启发式是否得到普遍认可。它是父级和子级之间的循环依赖关系。它也可能是代码气味。我们应该使用类似“桥接”的东西对象访问父对象。这取决于“依赖关系”的含义。如果要从子对象导航到父对象,则需要在某个位置使用边缘。可以使用“组件”避免类型依赖关系接口或类似。那么,双链接列表也是一个坏主意吗?不,它只是一个结构化工具,如果你想在任何情况下使用它,你都应该遵循上下文的原则。非常感谢,我理解你的意思。我无法在我的课堂上解释这种违规行为。但是我坚持在任何其他系统中使用这种启发式的真理(除尤德金外)