Я слышал, что это плохой дизайн - использовать instanceof или эквивалент (http://www.javapractices.com/topic/TopicAction.do?Id=31, , когда мы должны использовать instanceof, а когда нет ), с которым я могу согласиться, главным образом потому, что он может сделать код трудно использовать повторно.
Однако в некоторых случаях мне было трудно найти хорошую альтернативу instanceof. Например, скажем, что я хочу создать стратегию в реальном времени. Игра состоит из препятствий, зданий и танков, все они размещены на сетке, и каждое право занимает ровно одну единицу в сетке. Поэтому я создаю класс Entity, который является суперклассом классов Obstacle, Building и Tank. Сетка состоит из экземпляров Entity. Во время каждого обновления я хочу, чтобы каждый танк прицеливался и стрелял по вражескому танку в пределах досягаемости. Таким образом, простым способом сделать это было бы для каждого танка запросить сетку для всех сущностей в пределах диапазона танков, а затем выполнить итерацию по всем этим сущностям и проверить, являются ли они экземпляром класса 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 в описанной выше проблеме?
Спасибо!
Martin