【发布时间】:2011-06-11 15:09:27
【问题描述】:
对于框架的继承层次结构的最大深度以及何时使用多级继承或将它们加入单个类中的准则,是否有任何最佳实践?
从社区和围绕 Java 的框架的角度来看,一些在 Java 世界中运行良好的已建立实践/示例的参考会很好地回答。
【问题讨论】:
-
尽可能浅,尽可能深
标签: java inheritance frameworks
对于框架的继承层次结构的最大深度以及何时使用多级继承或将它们加入单个类中的准则,是否有任何最佳实践?
从社区和围绕 Java 的框架的角度来看,一些在 Java 世界中运行良好的已建立实践/示例的参考会很好地回答。
【问题讨论】:
标签: java inheritance frameworks
当谈到最佳实践时,还应考虑性能(内存使用)。
当你的类层次很深(非抽象)时,它会使用更多的内存。就像创建 3 级继承的最后一个子对象的新对象将使用比 9 级继承更少的内存。 根据应用的性质,除了其他帖子之外,还可以考虑这一点。
【讨论】:
在我看来,每个派生类都是“它自己的一个类”,这个类的客户,包括子类)通常不应该打扰或感兴趣,在这个类和 @ 之间有多少类987654322@班级。
因此,我的回答是:不,让层次结构尽可能深,只要它有意义/看起来合乎逻辑。不要让层次结构的深度影响是否折叠两个类的决定。由于每个子类都是其基类的细化,因此我的经验表明,深度超过 5 或 6 个类很少有意义。
要明确一点:正如其他人指出的那样,您应该更喜欢组合而不是继承。不过,对我来说,这似乎回答了一个稍微不同的问题。
根据this article,标准Java API中的最大深度是9。
【讨论】:
您可能正在寻找一个很好的规则,例如“不超过 5 级继承”,但我真的怀疑是否存在这样的规则。对象通常模拟现实世界的实体,而所有这些实体的社区从未就规则达成一致(据我所知)......
一个“最佳实践”无疑是:优先考虑组合而不是继承。遵循此准则:定义一个接口和实现,而无需进一步的超类。所有常见的字段和方法都带有行为和strategies
另一方面,我们有时会对已经具有深层实体层次结构的现实世界实体或结构进行建模。 动物分类就是一个例子或algebraic structures。对此类现有结构进行建模的框架将需要较深的类层次结构,因为它应该遵循现实世界以便易于理解。
【讨论】:
没有关于最大继承深度的最佳实践。当涉及到 java(以及任何 OO 语言)中的继承时,这是经验法则,而不是体积。
1_ 在实现继承之前检查“is a”关系是否为真。充电器是汽车。 (所以继承很好)。如果你这样做,那么无论如何你都不会得到巨大的继承树。 (轮子不是车,所以这里的继承是错误的)
2_ 如果“是”关系失败或者您有歧义,那么可能的继承不是方法。您需要确定类之间的共性并使用组合。(将公共代码重构为新类)。
3_如果你想建立一个类型层次结构,那么你应该使用接口继承(类型)而不是类级继承。 (可能其中一些陈述需要更多解释,但为此您可能需要拿起一些书。)
【讨论】:
据我所见(注意:这不是官方意见,只是我的观察),3-4 是合理的最大值。
另外,请记住 Effective Java 中的一个重要部分:
组合优于继承
【讨论】:
一般规则是层次结构越深,就越难理解特定方法和字段在哪里定义或/和重新定义。
但除了继承之外,您还需要注意其他一些因素,以保持代码复杂性可控。
最好的方法是使用代码度量工具并尝试在不同因素(代码行、类解耦和...)之间取得平衡
【讨论】:
最好的是每个班级都处理一堆类似的事情。
此类中的每个方法都处理一个动作/行为。
看看这个来自 DZone 的 refcard: http://refcardz.dzone.com/assets/download/refcard/54c22c8b0a53591ea9e0504fdfd4bada/rc130-010d-designing-quality_0.pdf
【讨论】:
您应该首先考虑您正在编写的代码的清晰度。具有更高层次的深度会使代码更易于阅读和维护,还是会使代码更难。很大程度上取决于您要解决的问题。
正如其他海报所建议的那样,您可以使深度太浅或太深。这是一个金发姑娘问题恕我直言。
【讨论】:
我认为,从维护的角度来看,您可以管理的继承层次结构越浅越好。通过多个层级向下跟踪错误,然后必须弄清楚应该在哪个层级修复它们可能是一个棘手的问题。
【讨论】: