我有两个 Akka Actor,它们以相同的方式响应某些消息,但以不同的方式响应其他消息。他们都响应同一组消息。想知道如何通过继承、镇静等方式使用他们的接收方法来设计我的两个 Actor ?我尝试使用“orElse”将来自其他特征的部分函数链接在一起,不幸的是,这会将类暴露给其特征的功能,而且我不确定特征的接收如何轻松访问 Actor 上下文。插入式模块化解决方案将是理想的,但我想知道这是否是某个地方已解决的问题?
最佳答案
确实有很多方法可以解决这个问题。我将从 OO 方式中列出两种(类似于@Randal Schulz 的建议)和一种更实用的方式。对于第一个可能的解决方案,您可以执行以下简单操作:
case class MessageA(s:String)
case class MessageB(i:Int)
case class MessageC(d:Double)
trait MyActor extends Actor{
def receive = {
case a:MessageA =>
handleMessageA(a)
case b:MessageB =>
handleMessageB(b)
case c:MessageC =>
handleMessageC(c)
}
def handleMessageA(a:MessageA)
def handleMessageB(b:MessageB) = {
//do handling here
}
def handleMessageC(c:MessageC)
}
class MyActor1 extends MyActor{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class MyActor2 extends MyActor{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
使用这种方法,您基本上定义了一个抽象 actor impl,其中
receive
函数是为所有处理的消息定义的。消息被委托(delegate)给 def
s 真正的业务逻辑在哪里。两个是抽象的,让具体的类定义处理,一个是完全实现的,用于逻辑不需要不同的情况。现在使用策略模式的这种方法的变体:
trait MessageHandlingStrategy{
def handleMessageA(a:MessageA)
def handleMessageB(b:MessageB) = {
//do handling here
}
def handleMessageC(c:MessageC)
}
class Strategy1 extends MessageHandlingStrategy{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class Strategy2 extends MessageHandlingStrategy{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class MyActor(strategy:MessageHandlingStrategy) extends Actor{
def receive = {
case a:MessageA =>
strategy.handleMessageA(a)
case b:MessageB =>
strategy.handleMessageB(b)
case c:MessageC =>
strategy.handleMessageC(c)
}
}
这里的方法是在构造过程中传入一个策略类,该类定义了对 a 和 c 的处理,无论如何 b 再次被处理。这两种方法非常相似,并且实现了相同的目标。最后一种方法使用部分函数链接,可能如下所示:
trait MessageAHandling{
self: Actor =>
def handleA1:Receive = {
case a:MessageA => //handle way 1
}
def handleA2:Receive = {
case a:MessageA => //handle way 2
}
}
trait MessageBHandling{
self: Actor =>
def handleB:Receive = {
case b:MessageB => //handle b
}
}
trait MessageCHandling{
self: Actor =>
def handleC1:Receive = {
case c:MessageC => //handle way 1
}
def handleC2:Receive = {
case c:MessageC => //handle way 2
}
}
class MyActor1 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{
def receive = handleA1 orElse handleB orElse handleC1
}
class MyActor2 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{
def receive = handleA2 orElse handleB orElse handleC2
}
在这里,设置了一些特征来定义 3 种消息类型的消息处理行为。具体参与者混合这些特征,然后在构建他们的
receive
时选择他们想要的行为。通过使用部分函数链接来实现。可能有很多其他方法可以做你所寻求的,但我只是想我会为你提供一些选择。希望能帮助到你。
关于scala - 我如何最好地在 Akka Actor 之间分享行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17383827/