Как вызвать правильный метод в Scala / Java на основе типов двух объектов без использования оператора switch?

В настоящее время я разрабатываю игру на Scala, в которой у меня есть несколько объектов (например, GunBattery, Squadron, EnemyShip, EnemyFighter), которые все наследуются от класса GameEntity. Игровые объекты транслируют интересные вещи в игровой мир и друг другу через систему событий / сообщений. Существует ряд сообщений EventMesssages (EntityDied, FireAtPosition, HullBreach).

В настоящее время каждый объект имеет получение (msg: EventMessage) , а также более конкретные методы приема для каждого типа сообщения, на которое он отвечает (например, receive (msg: EntityDiedMessage) ) . Общий метод receive (msg: EventMessage) - это просто оператор switch, который вызывает соответствующий метод приема в зависимости от типа сообщения.

Пока игра находится в разработке, список сущностей и сообщений (и какие сущности на какие сообщения будут отвечать) постоянно меняется. В идеале, если я хочу, чтобы игровая сущность могла получать новый тип сообщения, я просто хочу иметь возможность закодировать логику для ответа, а не делать этого и должны обновлять оператор соответствия где-либо еще.

У меня была одна мысль: вытащить методы приема из иерархии сущностей Game и создать ряд функций, таких как def receive (e: EnemyShip, m: ExplosionMessage) и def receive (e: SpaceStation, m: ExplosionMessage) , но это усугубляет проблему, поскольку теперь мне нужен оператор сопоставления, охватывающий типы игровых сущностей сообщения и .

Похоже, это связано с концепциями Двойной и Множественной отправки и, возможно, с шаблоном «Посетитель», но у меня возникли некоторые проблемы с осознанием этого. Я не ищу решение ООП как таковое, однако я бы хотел избежать размышлений, если это возможно.

РЕДАКТИРОВАТЬ

Проведя дополнительное исследование, я думаю, что я ищу что-то вроде Clojure defmulti .

Вы можете сделать что-то вроде:

(defmulti receive :entity :msgType)

(defmethod receive :fighter :explosion [] "fighter handling explosion message")
(defmethod receive :player-ship :hullbreach []  "player ship handling hull breach")

9
задан Michael 21 December 2011 в 16:12
поделиться