Я пишу симулятор, который имеет несколько интерфейсов, которые реализуют все моделируемые объекты. Интерфейс Entity
содержит методы, которые должны быть у всех объектов, такие как извлечение идентификатора и увеличение временного шага для состояния объекта. Collidable
расширяет Entity
и представляет что-либо с объемом и положением, которые следует учитывать при выполнении алгоритмов обнаружения столкновений. Поле
расширяет Entity
и представляет все, что сопоставляет местоположение со значением; они используются для моделирования таких вещей, как магнитные поля, которые пронизывают мир, но не имеют объема или физической формы. RigidBody
— это класс, который реализует Collidable
и предоставляет алгоритмы динамики твердого тела.У меня есть класс World
, который управляет всеми Entities
и имеет методы для опережения часов симулятора и разделения мира, чтобы сделать обнаружение столкновений более эффективным.
Моя проблема связана с получением подтипов Entity
из World
. Первоначально в World
была только карта Entities
с ключом ID, и для получения Field
или RigidBody
существовали методы, возьмите Entity
с карты и выполните проверку instanceof
плюс приведение к нужному подтипу. Однако я прекрасно понимаю, что использование instanceof
осуждается, поэтому я попробовал другой подход.
В настоящее время у меня есть отдельные карты в World
для каждого интерфейса. Например, есть карта для Collidables
, а также карта для всех Entities
. Метод addCollidable()
будет добавлять данные к обеим картам, а getCollidable()
будет извлекать данные только из карты Collidable
. Это позволяет избежать instanceof
, но мне все равно кажется плохим дизайном. Если я придумаю другой интерфейс для расширения Entity
, мне понадобится другая карта в World
и соответствующие методы.
Мне кажется, что эта проблема не так уж неясна, так что же обычно делают в такой ситуации?
РЕДАКТИРОВАТЬ
Я не думаю, что здесь будет работать шаблон Visitor, так как Visitor позволяет выполнять диспетчеризацию для конкретного типа, а некоторые из моих методов поиска требуют получения типов интерфейса.Например, Visitor будет работать, если World
нужны только методы для получения RigidBodies
и других подобных конкретных классов, но я не могу создать метод, который извлекает все Collidables
с помощью Visitor. .