对Akka Actors与Java对象的混淆

时间:2013-04-11 12:58:36

标签: design-patterns akka actor

我正在努力让自己熟悉Akka和Actors,但我想我错过了一点。我的接收循环变得过大。例如:

class Node extends Actor {
  def receive {
    case "pause" => pause
    case "resume" => resume
    case "methodX" => methodX
    case "methodY" => methodY
    case "methodZ" => methodZ
  } 
}

我是Actors,Scala和函数式编程的新手。我认为我在对象领域的经验正在渗透到我的演员定义中,所以我的问题是寻找如何以“正确”的方式定义Actor的API并避免这种无类型消息爆炸的指导。

1 个答案:

答案 0 :(得分:1)

有多少消息都取决于您要封装的内容。一个好的规则是尝试让actor专注于一个任务,然后让它将事物委托给其他actor(从而使界面变小)。同时让演员无国籍并且在你发送的信息中拥有状态将会有很大的帮助。

保持消息不可变是很重要的,但这并不意味着它们必须是字符串。您可以定义您接受的消息,并使用案例类发送(以获得不变性),并让编译器为您做一些检查,如果您使它们扩展密封特征。这是一个例子,编译器会抱怨你的匹配并非详尽无遗,因为你没有在接收中处理FooMessage。

object MyActor {
  // these are the messages we accept
  sealed abstract trait Message
  case class FooMessage(foo: String) extends Message
  case class BarMessage(bar: Int) extends Message

  // these are the replies we send
  sealed abstract trait Reply
  case class BazMessage(foo: String) extends Reply
}

class MyActor extends Actor {
  import MyActor._
  def receive = {
    case message: Message ⇒ message match {
      case BarMessage(bar) => sender ! BazMessage("Got " + bar)
    }
  }
}

你也应该尝试在火中考虑演员并在此期间做其他事情(开火和忘记声音苛刻)。那你应该使用tell(!)而不是问(?)。不要将消息发送视为方法调用。这将使您的代码阻止而不是缩放。

演员使用的一个常见例子是拥有一个演员链,其中每个演员执行一项任务,然后将转换后的消息转发给下一个演员。最后你回复发起连锁的演员,或者他说你应该回复的任何人,从而缩短中间的所有演员。不需要消息传递下来然后备份链。

希望这会给你一些想法。