Я слышал, что использование 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 в описанной выше проблеме?