存储接口实现和检索特定实现的好模式是什么?

时间:2012-04-09 04:29:48

标签: java interface subclass simulation

我正在编写一个模拟器,它有几个接口,所有模拟对象都可以实现。 Entity接口具有所有对象必须具有的方法,例如ID检索和提升对象状态的时间步长。 Collidable扩展Entity,代表在碰撞检测算法运行时应考虑的具有体积和位置的任何内容。 Field扩展Entity,代表将位置映射到值的任何内容;这些用于模拟诸如渗透到世界但没有体积或物理形式的磁场之类的东西。 RigidBody是一个实现Collidable并提供刚体动力学算法的类。我有一个World类来管理所有Entities,并且具有推进模拟器时钟和分区世界的方法,以便使碰撞检测更有效。

我的问题涉及从Entity检索World个子类型。最初,World只有Entities的地图标识为ID,并且为了解除FieldRigidBody,会有一些方法可以抓住Entity对地图执行instanceof检查以及对所需子类型进行强制转换。我很清楚instanceof的用法是不受欢迎的,所以我尝试了另一种方法。

目前,我在每个界面的World内都有单独的地图。例如,Collidables的地图以及所有Entities的地图都有。 addCollidable()方法将添加到两个地图中,getCollidable()将仅从Collidable地图中检索。这避免了instanceof,但对我来说似乎仍然是糟糕的设计。如果我想出另一个扩展Entity的界面,我需要World中的另一个地图和相应的方法。

我觉得这个问题并不是非常模糊,所以在这种情况下通常会做什么?

修改

我不相信访问者模式会在这里工作,因为访问者允许您调度具体类型,并且我的一些检索方法需要检索接口类型。例如,如果World仅需要方法来检索RigidBodies和其他此类具体类,则访问者将工作,但我无法创建一个方法来检索具有访问者的所有Collidables

3 个答案:

答案 0 :(得分:1)

您可以使用的是访问者模式,本访问者模式教程使用它来解决您遇到的类似问题。 http://www.youtube.com/watch?v=KSEyIXnknoY

答案 1 :(得分:1)

使用instanceof是不受欢迎的,因为经常出现在提示不完整封装的上下文中。例如,instanceof有时用于区分不同类型的对象,然后根据其类型对它们进行操作。更简洁的方法是将代码放入对象的相应类中,并使用polymorphism代替。因此,而不是从不使用instanceof,而是问问自己当前对instanceof的使用是否可能合法

换句话说: 是否可以将依赖于实体类型的代码移动到相应的实体类中?当然,一旦你得出结论,就应该记录下来,因为事情可能会发生变化。

BTW我认为您可以使用Map<Class,List<Entity>>轻松概括当前设计,这样您就可以将实体列表保留为任意数量的类型。您还可以拥有一个数组Class[] types = {...},其中包含需要区分的所有类型。 现在,在instanceof方法中的for循环中只需要一个add/removeEntity(...)运算符,它将遍历需要区分的所有类型,并将实体添加到/从中删除所有相关清单。

答案 2 :(得分:0)

对我来说似乎是合理的,你为世界级的可碰撞物使用了额外的场,因为它是一个特殊的数据子集,需要专门的处理。

我唯一会改变的(主要是由于个人品味),使用List<Collidable>作为类型,因为根据您的需要 - 迭代所有这些以进行碰撞检查 - 列表更快更好更轻量级的方法。