В настоящее время я разрабатываю игру в Scala, в которой у меня есть несколько сущностей (например, GunBattery, Squadron, EnemyShip, EnemyFighter), которые все наследуются от класса GameEntity. Игровые объекты транслируют вещи, представляющие интерес для игрового мира и друг друга, через систему событий / сообщений. Существует несколько сообщений EventMesssages (EntityDied, FireAtPosition, HullBreach).
В настоящее время каждый объект имеет receive(msg:EventMessage)
, а также более конкретные методы получения для каждого типа сообщений, на которые он отвечает (например, receive(msg:EntityDiedMessage)
). Общий метод receive(msg:EventMessage)
- это просто оператор switch, который вызывает соответствующий метод приема в зависимости от типа сообщения.
Поскольку игра находится в разработке, список сущностей и сообщений (и какие сущности будут отвечать на какие сообщения) является плавным. В идеале, если я хочу, чтобы игровая сущность могла получать новый тип сообщения, я просто хочу иметь возможность кодировать логику ответа, а не делать то, что и должны обновлять оператор сопоставления где-либо еще.
Одна мысль, которая у меня была, состоит в том, чтобы вытащить методы получения из иерархии сущностей Game и иметь ряд функций, таких как def receive(e:EnemyShip,m:ExplosionMessage)
и def receive(e:SpaceStation,m:ExplosionMessage)
, но это усугубляет проблему, так как теперь мне нужно выражение match, чтобы охватить оба сообщение и типы игровых сущностей.
Это, похоже, связано с понятиями Double и Multiple dispatch и, возможно, с шаблоном Visitor, но у меня возникли некоторые проблемы, когда я оборачиваюсь вокруг него. Я не ищу решение ООП как таковое, однако я хотел бы избежать отражения, если это возможно.
EDIT
Проводя еще какие-то исследования, я думаю, что я ищу что-то вроде Clojure defmulti
.
Вы можете сделать что-то вроде:
(defmulti receive :entity :msgType)
(defmethod receive :fighter :explosion [] "fighter handling explosion message")
(defmethod receive :player-ship :hullbreach [] "player ship handling hull breach")