需要在运行时Java确定对象的类型。糟糕的设计?

时间:2011-10-17 23:35:33

标签: java interface runtime containers typechecking

我正在写一个粒子传输代码。在此代码中,物理对象实现了接口Volume。 Volume的一个实现者是这个代码感兴趣的例子 - Particle类。在我的设计中,Volumes包含其他Volumes一直到最小的Volume实现者Particle。只要粒子想通过具有交互的卷不受监控地飞行,这将非常有效。

然而,当我想实现某种粒子探测器Volume时,会记录有关粒子的信息,我有一个问题。 Volume接口不包含获取Particle所具有的特殊信息类型的方法。如果一个粒子进入探测器体积,我将不得不做一些事情,比如在我将它投射到粒子体积并调用粒子方法之前用反射检查它的类型。一般来说(从我所看到的)这种类型的东西被标记为“糟糕的设计”标签。

我可以这样做,以便只有粒子可以跨越Volume接口中的Volume边界(将接口绑定到特殊情况粒子),但我真的不想对我的代码施加限制。我可能希望允许卷移动并稍后加入。

这听起来像是一个糟糕的设计吗?还有另一种明显的方法可以解决这个问题吗?如果需要,我会附上代码,但一般问题似乎与我的细节无关(并且完全独立于语言)。

提前致谢。我非常感谢SO的所有知识。

3 个答案:

答案 0 :(得分:1)

从我读过的内容来看,Java中的动态转换并不算糟糕。简单类型检查远不如使用完整的Reflection API。

您可以尝试动态广播并捕获可能的ClassCastException,也可以在投射前进行isinstance Particle检查。

从概念上讲,Particles实现一个接口可能更有意义,该接口表明它们具有粒子检测器想要记录的信息。如果不了解您的设计,我们就不能说了。

答案 1 :(得分:1)

听起来像颗粒不是真正的体积,因为体积可以包含其他体积而颗粒不能做到这一点。这违反了Liskov Subsitiution Principle。您应该考虑不让粒子继承自Volumes接口,而是继承其他东西。

答案 2 :(得分:0)

如果一个人无法控制可能存储在引用中的所有类型,并且某些类型将具有其他类型缺少的功能,则最实用的方法可能是为相关功能定义接口,检查对象是否实现了所需的接口,如果是,则转换对象。但是,如果可以控制类型,其他方法可能会更好。

例如,如果一个应用程序有一个对象集合,这些对象都是从该应用程序独有的公共基类型继承的,并且当某些事情发生时需要通知新的对象类型,那么可以为这种通知定义一个接口并让应用程序循环遍历所有对象并向实现该接口的对象发送通知,但是也可以向基类型添加基本类型的无任何“notify”方法,并对集合中的所有对象调用该方法。最好还有一种方法来测试通知是否必要(允许应用程序选择维护只包含需要此类通知的对象的集合),但在许多情况下,调用无操作方法将更简单,比测试是否需要调用方法更有效。