我听说使用 instanceof 或等效项(http://www.javapractices.com/topic/TopicAction.do?Id=31,什么时候应该和不应该使用 instanceof ?)是不好的设计,我可以同意on,主要是因为它会使代码难以重用。
然而,在某些情况下,我发现很难找到一个好的替代 instanceof 的方法。例如,假设我想制作一款实时策略游戏。游戏由障碍物、建筑物和坦克组成,所有这些都放置在一个网格上,每个实体恰好占据网格中的一个单元。所以我创建了实体类,它是障碍、建筑和坦克类的超类。网格由实体的实例组成。在每次更新期间,我希望每辆坦克都能瞄准射程内的敌方坦克并射击。因此,一个简单的方法是让每个坦克向网格询问坦克范围内的所有实体,然后遍历所有这些实体并检查它们是否是 Tank 类的实例。
作为使用 instanceof 的替代方法,我唯一的尝试是使用设计模式Visitor。访问者被一个实体接受,该实体(entity->acceptVisitor(visitor))
又调用其中一种方法visitor->visitObstacle(this)
,visitor->visitBuildig(this)
或visitor->visitTank(this)
。然而,这迫使我创建了大量的访问者,对于我想在实体上进行的每一项任务几乎都有一个新的访问者。另一个问题是,在许多情况下,访问者在实体上调用相同的方法,无论它是从哪个类构造的。例如,当一个实体想要检查另一个实体是否静止时,可能会发生这种情况:
#Python代码:
class StationaryEntityGatherVisitor:
def __init__(self):
self.stationaryEntities = []
def visitObstacle(self, obstacle):
self._addIfStationary( obstacle )
def visitBuildig(self, building):
self._addIfStationary( building )
def visitTank(self, tank):
self._addIfStationary( tank )
def _addIfStationary(self, entity):
if entity.isStationary():
self.stationaryEntities.append( entity )
def getStationaryEntities():
return self.stationaryEntities
当然,在这种情况下,我可以让实体直接询问另一个实体是否是静止的,而不是让访问者这样做。但在那种情况下,我在检查实体的属性时会不一致。让向实体询问某些属性的方法(直接或通过访问者)有所不同,这取决于我是否需要检查实体类型,在我看来,这似乎是一个非常奇怪的设计。
那么,除了在上述问题中使用 instanceof 之外,您还有其他选择吗?