我目前正在 Scala 中开发一款游戏,其中有许多实体(例如 GunBattery、Squadron、EnemyShip、EnemyFighter),它们都继承自 GameEntity 类。游戏实体通过事件/消息系统向游戏世界和彼此广播感兴趣的事物。有许多 EventMesssage(EntityDied、FireAtPosition、HullBreach)。
目前,每个实体对于它响应的每种消息类型(例如)都有一个receive(msg:EventMessage)
以及更具体的接收方法。receive(msg:EntityDiedMessage)
通用receive(msg:EventMessage)
方法只是一个 switch 语句,它根据消息的类型调用适当的接收方法。
随着游戏的开发,实体和消息的列表(以及哪些实体将响应哪些消息)是流动的。理想情况下,如果我希望游戏实体能够接收新的消息类型,我只想能够编写响应的逻辑,而不是这样做并且必须在其他地方更新匹配语句。
我的一个想法是将接收方法从游戏实体层次结构中提取出来并具有一系列函数,例如def receive(e:EnemyShip,m:ExplosionMessage)
和 defreceive(e:SpaceStation,m:ExplosionMessage)
但这使问题更加复杂,因为现在我需要一个匹配语句来涵盖消息和游戏实体类型。
这似乎与双重和多重调度的概念以及访问者模式有关,但我在理解它时遇到了一些麻烦。我并不是在寻找 OOP 解决方案本身,但是如果可能的话,我想避免反思。
编辑
做一些更多的研究,我认为我正在寻找类似于 Clojure 的东西defmulti
。
您可以执行以下操作:
(defmulti receive :entity :msgType)
(defmethod receive :fighter :explosion [] "fighter handling explosion message")
(defmethod receive :player-ship :hullbreach [] "player ship handling hull breach")