Design patterns 关于Akka参与者与Java对象的混淆
我试图让自己熟悉阿克卡和演员,但我想我遗漏了一点。我的接收循环变得过大。例如:Design patterns 关于Akka参与者与Java对象的混淆,design-patterns,akka,actor,Design Patterns,Akka,Actor,我试图让自己熟悉阿克卡和演员,但我想我遗漏了一点。我的接收循环变得过大。例如: class Node extends Actor { def receive { case "pause" => pause case "resume" => resume case "methodX" => methodX case "methodY" => methodY case "methodZ" => methodZ } }
class Node extends Actor {
def receive {
case "pause" => pause
case "resume" => resume
case "methodX" => methodX
case "methodY" => methodY
case "methodZ" => methodZ
}
}
我不熟悉演员、Scala和函数式编程。我认为我在对象领域的经验正在泄漏到我的参与者定义中,因此我的问题是如何以“正确”的方式定义参与者的API并避免这种非类型化的消息爆炸 有多少条消息取决于您试图封装的内容。一个好的规则是尽量让参与者专注于一个任务,然后让它将事情委托给其他参与者(从而使界面变小)。另外,使参与者无状态,并在您发送的消息中包含状态也会有很大帮助 保持消息不变很重要,但这并不意味着它们必须是字符串。您可以定义接受的消息,并与case类一起发送(以获得不变性),如果您使它们扩展了密封特性,则让编译器为您执行一些检查。下面是一个例子,编译器会抱怨您的匹配是非穷举的,因为您没有在receive中处理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(!)而不是ask(?)。不要将消息作为方法调用发送。这将使您的代码块,而不是规模
参与者使用的一个常见示例是有一个参与者链,其中每个参与者执行一个任务,然后将转换后的消息转发给下一个参与者。最后,你要回答那个发起连锁的演员,或者他说你应该回答的任何人,从而在中间剪短所有演员。消息不需要向下传播,然后再向上传播
希望这能给你一些想法。谢谢你花时间回答。“使参与者无状态化”——如果消息传递没有保证,这是个什么好主意?(顺便说一句,我正在与remoteactors合作,因此不交付是一个问题)。我喜欢关于密封特征的观点,这非常有用。关于演员链的一点很有趣——它听起来像是一个特定于演员的设计模式。也许我可以在某个地方找到这些东西的清单