В настоящее время я разрабатываю игру на 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")