【发布时间】:2018-03-30 00:51:16
【问题描述】:
我需要通过内部对象分解案例类,并且案例变得非常长。假设我只针对按类型分解的“上下文”内部对象的第一个参数的情况,是否有更好的方法来编写?
编辑:更改示例以反映讨论
// context should be any opaque type that you want returned to you in your result message
case class PopulateFeedVersionMessage(inoutContext: Any, sectionId : Int, feedId : Int, newVersion : String, oldVersion : String)
trait PopulateDBReturnableMessage {
val inputMessage : PopulateFeedVersionMessage
}
case class PopulateFeedFileNotExistsError(inputMessage : PopulateFeedVersionMessage, errorMessage : String) extends PopulateDBReturnableMessage
case class PopulateFeedUploadError(inputMessage : PopulateFeedVersionMessage, errorMessage : String) extends PopulateDBReturnableMessage
case class PopulateFeedRuntimeError(inputMessage : PopulateFeedVersionMessage, errorMessage : String) extends PopulateDBReturnableMessage
case class PopulateDBResult(inputMessage: PopulateFeedVersionMessage, localNewDBPath : String, localOldDBPath : String, feedType : DatafeedType) extends PopulateDBReturnableMessage
假设在父演员中我这样做:
childActor ! PopulateFeedVersionMessage(inoutContext = interestingContextObjectForThisParticularMessage,sectionId = 1, feedId = 2, newVersion = "Some new version", oldVersion = "some old version")
在子actor中,我处理消息并决定使用PopulateDBReturnableMessage 类型(可以是result 或error 类型)进行响应
// child
override def receive = {
case message : PopulateFeedVersionMessage => sender ! handle(message)
}
def handle(message : PopulateFeedVersionMessage) = {
...
// lets say we had an upload error because the disk is full or 401 or server down or what ever we can supply in the error message
PopulateFeedUploadError(inputMessage = message, errorMessage : "The disk is full")
}
现在回到父演员:
def receive = {
case MessageType1 => {
... deciding what to do...
... decided to spawn a child actor with a context of interest...
childActor ! PopulateFeedVersionMessage(inoutContext = interestingContextObjectForThisParticularMessage,sectionId = 1, feedId = 2, newVersion = "Some new version", oldVersion = "some old version")
}
// async handling the return message of the child with the context
case m : PopulateDBReturnableMessage => m match {
case PopulateFeedFileNotExistsError(inputMessage: PopulateFeedVersionMessage, errorMessage: String) => {
// need to decompose the inputMessage.context as a inInterestingContextObjectForThisParticularMessage type
}
case PopulateFeedUploadError(inputMessage: PopulateFeedVersionMessage, errorMessage: String) => {
}
case PopulateFeedRuntimeError(inputMessage: PopulateFeedVersionMessage, errorMessage: String) => {
// need to decompose the inputMessage.context as a inInterestingContextObjectForThisParticularMessage type
}
case PopulateDBResult(inputMessage: PopulateFeedVersionMessage, localNewDBPath: String, localOldDBPath: String, feedType: DatafeedType.DatafeedType) => {
// need to decompose the inputMessage.context as a inInterestingContextObjectForThisParticularMessage type
}
case _ =>
}
}
【问题讨论】:
-
如果可能的话,我会质疑设计决策。为什么需要
Any的上下文?看起来像一个漏洞。 -
因为它作为无法输入的akka消息的inout参数传递
-
基本上,actor的输入消息包含一个参数,该参数可以作为不透明状态传回其发送者,以识别它运行的上下文的某些属性(例如可以是时间/日期/计数器/或与其运行相关的其他状态)
-
并且输入输出状态的类型可能会根据可能出现的某些条件而改变(即,在某些情况下,传递一个日期可能很有趣,但在其他情况下,传递一个哈希值可能会很有趣可以识别状态的某种“事物”)
-
我明白了。
foo是否关心这些类的特定(重复)属性,还是它们通常不同?
标签: scala syntax pattern-matching traits