我已经使用 Akka 和 Scala 大约一个月了,我对用消息替换显式接口感到有些困扰。考虑以下简单的 Akka Actor:
case class DoMyHomework()
class Parent extends Actor {
def receive = {
case d: DoMyHomework => // do nothing
}
}
向此参与者发送 DoMyHomework 消息的参与者或非参与者代码,如下所示:
ActorRef parent = ...
parent.ask(DoMyHomework)
不知道结果会是什么。答案的类型是什么?我会得到答案吗?我可以例外吗?等等。
修复似乎是记录案例类......但是如果其他一些演员也收到相同的案例类怎么办。那么接收该消息的文档应该在actor本身中。
为了稍微清理一下,我想到了以下操作:
trait SomeoneSmarter {
def wouldYouDoMyHomework: Future[Boolean]
}
class Parent extends Actor with SomeoneSmarter {
case class DoMyHomework()
def wouldYouDoMyHomework = {
(self ? DoMyHomework()).mapTo(Boolean)
}
def receive = {
case d: DoMyHomework =>
// TODO: If I'm busy schedule a false "No way" reply for a few seconds from now.
// Just to keep their hopes up for a while. Otherwise, say sure right away.
}
}
所以,我和同事聊起这件事,其中一个反应是“你不忠于演员模型”。
首先,我非常感谢长期使用 Actors 的人们提供的一些指导。所有的消息都会变得笨拙吗?您最终是否将消息传递隐藏在接口后面?
我提议的演员仍然可以选择在他们之间发送消息,订阅事件流,所有你期望从 Akka 得到的东西。该界面为您提供了一种久经考验的方式来了解您在说什么。它有助于在 IDE 中进行编码等等。为什么演员的用户需要知道它是演员(除非它也是演员并且与演员紧密耦合)?
我得到的另一个反应是“看起来你想要一个 TypedActor”。但是在阅读了有关 TypedActor 的内容后,我并不相信。当然,TypedActor 为我省去了创建这些内部消息的麻烦。但是,至少从 http://doc.akka.io/docs/akka/snapshot/scala/typed-actors.html的代码示例中,我得到的印象是 TypedActor 仅作为一个块周围的代理工作您想要封装的代码,或使线程安全,或者根本不直接从当前线程调用。您编写的代码只是实现和接口。您不会弄乱参与者本身(代理) - 例如,如果您希望您的实现定期工作或订阅事件流,或做任何与接口无关的事情。
我还阅读了http://letitcrash.com/post/19074284309/when-to-use-typedactors并没有发现该示例更具启发性。我可能只是不了解 TypedActor(并不是说我声称已经真正了解 Actors)。
提前感谢您的帮助。
皮诺