2013-04-11 74 views
0

我试图让自己熟悉Akka和Actor,但我想我错过了一点。我的接收环路变得过大。例如:关于Akka Actor与Java Objects的混淆

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

我是新来的演员,斯卡拉和函数式编程。我认为我在对象土地上的经验渗透到我的演员定义中,所以我的问题是寻找关于如何定义Actor'API'的方法并避免这种无类型消息爆炸的指导。

回答

1

有多少条消息都取决于您试图封装的内容。一条很好的规则是尽量让演员专注于一项任务,然后让其将任务委托给其他演员(从而使界面变小)。让演员无国籍,让你发送的消息中的状态将会有所帮助。

保持消息不变是很重要的,但这并不意味着它们必须是字符串。你可以定义你接受的消息,并用case类发送(以获得不变性),并让编译器为你做一些检查,如果你让它们扩展一个密封的特征。这里有一个例子,编译器会抱怨你的匹配不完全,因为你没有在接收中处理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(!)而不是问(?)。不要将消息发送视为方法调用。这会使你的代码被阻塞而不能扩展。

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

希望这给你一些想法。

+0

感谢您花时间回答。 Re'让演员无国籍' - 如果邮件传递得不到保证,这是个好主意吗? (顺便说一句,我正在与远程工作,所以不交付是一个问题)。我喜欢关于密封特征的观点,这非常有用。关于演员链的一点很有趣 - 这听起来像是一个演员特定的设计模式。也许我可以在某处找到这些列表 – Hamy 2013-04-13 20:28:48