在您的示例中,您对相关消息的处理已经被分解为一个方法,这使得这很简单:
trait RequestContext
case class MessageA(req: RequestA, ctx: RequestContext)
object MessageA {
def apply(req: RequestA)(implicit ctx: RequestContext) = MessageA(req, ctx)
}
case class MessageB(req: RequestB, ctx: RequestContext)
object MessageB {
def apply(req: RequestB)(implicit ctx: RequestContext) = MessageB(req, ctx)
}
class Example extends Actor {
def receive = {
case MessageA(req, ctx) => handle(req)(ctx)
}
def handle(req: RequestA)(implicit ctx: RequestContext): Unit = {
val intermediateResult = businessLogic(req) // could take implicit ctx as well
actorB ! MessageB(intermediateResult)
}
}
但正如您所见,在声明消息类型时仍然存在一些开销,并且handle
方法的签名也需要更改。这个方案是否值得取决于这些隐含值的消费者和生产者之间的比例(即,如果不止一件事物handle
使用上下文,它更有意义)。
上述变化可能是:
case class MessageA(req: RequestA, ctx: RequestContext)
object MessageA {
def apply(req: RequestA)(implicit ctx: RequestContext) = MessageA(req, ctx)
implicit def toContext(implicit msg: MessageA) = msg.ctx
}
case class MessageB(req: RequestB, ctx: RequestContext)
object MessageB {
def apply(req: RequestB)(implicit ctx: RequestContext) = MessageB(req, ctx)
implicit def toContext(implicit msg: MessageB) = msg.ctx
}
...
def handle(implicit ma: MessageA): Unit = {
val intermediateResult = businessLogic(req)
actorB ! MessageB(intermediateResult)
}