如何在不使用switch语句的情况下基于两个对象的类型在Scala / Ja
我目前正在
Scala开发一款游戏,我有许多实体(例如GunBattery,Squadron,EnemyShip,EnemyFighter),这些实体都继承自GameEntity类.游戏实体通过事件/消息系统向游戏世界和彼此广播感兴趣的事物.有许多EventMesssages(EntityDied,FireAtPosition,HullBreach).
目前,每个实体都有一个接收(msg:EventMessage)以及它响应的每种消息类型的更具体的接收方法(例如receive(msg:EntityDiedMessage)).通用receive(msg:EventMessage)方法只是一个switch语句,它根据消息类型调用适当的receive方法. 随着游戏的开发,实体和消息列表(以及哪些实体将响应哪些消息)是流动的.理想情况下,如果我希望游戏实体能够接收新的消息类型,我只是希望能够为响应编写逻辑代码,而不是那样做,并且必须更新匹配语句. 我曾经想到的一种方法是将接收方法从游戏实体层次结构中拉出来,并具有一系列函数,如def接收(e:EnemyShip,m:ExplosionMessage)和def接收(e:SpaceStation,m:ExplosionMessage),但这个化合物现在的问题我需要一个匹配语句来涵盖消息和游戏实体类型. 这似乎与Double和Multiple调度的概念有关,也许与访客模式有关,但我在绕过它时遇到了一些麻烦.我本身并不是在寻找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") 解决方法
您可以在Scala中轻松实现多个调度,尽管它没有一流的支持.通过下面的简单实现,您可以按如下方式对示例进行编码:
object Receive extends MultiMethod[(Entity,Message),String]("") Receive defImpl { case (_: Fighter,_: Explosion) => "fighter handling explosion message" } Receive defImpl { case (_: PlayerShip,_: HullBreach) => "player ship handling hull breach" } 您可以像使用任何其他功能一样使用多方法: Receive(fighter,explosion) // returns "fighter handling explosion message" 请注意,每个多方法实现(即defImpl调用)必须包含在顶级定义(类/对象/特征体)中,并且由您决定在使用该方法之前发生相关的defImpl调用.这个实现有很多其他的限制和缺点,但我会将这些作为练习留给读者. 执行: class MultiMethod[A,R](default: => R) { private var handlers: List[PartialFunction[A,R]] = Nil def apply(args: A): R = { handlers find { _.isDefinedAt(args) } map { _.apply(args) } getOrElse default } def defImpl(handler: PartialFunction[A,R]) = { handlers +:= handler } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |