为什么Akka Actor只有一个能够接收消息的onReceive()方法

时间:2014-05-21 14:12:31

标签: java scala akka actor

现在想。为什么Akka Actor Model只有一个onReceive()方法。

{我还没有在制作中使用演员,所以如果我误解了某些内容,请原谅我。只考虑一般的模型。}

为什么我们不需要随意的方法给我们的演员?

就像为什么不说我们演员中的公共方法一样,他们会超过mail-box,将这些电话推到that function call queue

像这样:

class MyActor extends ... {
 public void doSomething1(message:String) {...}
 public void doSomtething2(message:MyMessage) {}
}

我的观点是,拥有许多代表用户调用的方法而不是覆盖所有instanceof(this)instanceof(that)

可能会更好

有方法,但没有oncece一个有很多案例,使代码更具可读性(对我而言),并提供更好的代码导航能力,利用IDE帮助。

更新

请阅读TypedActors

我想知道为什么人们通常喜欢使用无类型的演员而不是打字的演员(我已经读过Akka书中的一些章节,似乎Untyped的那些是默认的方式)?

类似的似乎(对我来说[至少在那一刻])使代码更具可读性 - 更少' instanceof' /'案例' - 参与。更像面向对象。更类似Java& scala种语言是 - 类型(安全)语言。

即使在pattern-matching中使用scala并不像方法列表那么清晰。正如我所说的 - 在IDE中更容易导航,只需点击该方法即可将您带到确切位置..而不是经过case: this .. case: that

我很想说case / instanceof - 方式让我想起来自WinApi的旧东西

4 个答案:

答案 0 :(得分:2)

我不是Akka团队的一员,所以我只能猜到这里。但是我理解为什么我会反对你所描述的方法。

  1. 当在接收功能中未实现消息时,它什么都不做。最重要的是,它不会破坏我的系统!
  2. 我可以撰写行为 - 比方说,我想要由initializationHandler orElse lifecycleHandler orElse unknownMessageHandler组成的未初始化行为,并轻松切换到businnessProcessHandler orElse lifecycleHandler orElse unknownMessageHandler,在您的情况下,这将导致代码重复,和/或存储本地状态
  3. 我可以参数化我的行为!您可以安全地使用def receive = businessProcessHandler(timeout = 5 millis)之类的代码,并且我的部分函数将具有超时可用,而无需将其实际存储在actor对象中。

答案 1 :(得分:1)

用于无类型actor的Java onReceive()方法是在原始Scala receive()方法之后建模的 - 因为Scala具有模式匹配,不需要在那里执行instanceof,只需基于模式进行分解。遗憾的是,Java没有模式匹配,因为在许多情况下,分解实际上提供了比面向对象的方法调用更好的抽象级别。作为一个事件驱动的框架,Akka的无类型演员可以通过基于模式匹配的分解来响应任何复杂的消息类型,例如

def receive = {
  case head :: tail => println("Not empty list")
  case 1 :: tail => println("list starting with 1 with an arbitrary tail")
  case Nil => println("Empty list")
  case Person("Joe", lastName) => println(s"Hello Joe $lastName")
}

如果有帮助,你可以使用typed actors代替Java,因为在Java的情况下,面向对象的分解可能比instanceof更好,因为模式匹配不可用。

键入的actor允许您进行方法调用而不是消息传递。键入的actor支持异步"即发即弃"方法,异步的future-returns方法,以及阻塞方法。由于类型演员不是演员计算模型的一部分,因此它们是谨慎使用的,它们是Akka在消息传递框架中支持面向对象思维方式的方式,以及演员模型和OO" RPC"不一样。 Here是一篇很好的帖子,涵盖了其中的一些内容。正如Akka自己的文档所说:

  

TypedActors很容易被滥用为RPC,这是众所周知的漏洞。因此,当我们谈论使高度可扩展的并发软件更容易正确编写时,TypedActors不是我们首先想到的。他们有自己的利基,谨慎使用它们。

答案 2 :(得分:0)

另请注意,键入的actor不允许您切换行为,FSM风格(Akka有FSM API)。据我所知,你不能应用成为/不成为类型的演员,但你可以对无类型的演员。根据用例,这可能相关也可能不相关。

答案 3 :(得分:0)

如果你想要一个合理的模式,你可以像这样使用Java 8及以上版本支持的lambda表达式

import akka.actor.AbstractActor;
import akka.japi.pf.ReceiveBuilder;

public class Root extends AbstractActor {
    public Root() {
       receive(ReceiveBuilder
            .match(DoThis.class, this::doThis)
            .match(DoThat.class, this::doThat).build());
    }

    private doThis(DoThis doThis) {}
    private doThat(DoThat doThat) {}
}