2014-11-03 131 views
4

Akka和我正在认识对方。Akka演员道具工厂

来源:Akka 2.3.6 (current) Actor Recommended Practice

这是一个例子演员叫DemoActor:

class DemoActor(magicNumber: Int) extends Actor { 
    def receive = { 
    case x: Int => sender() ! (x + magicNumber) 
    } 
} 

建议措施DOC的部分它指出:“这是对提供工厂方法是个好主意每个Actor的伴侣对象帮助保持适当Props的创建尽可能接近actor的定义。“他们做哪些这样的:

object DemoActor { 
    def props(magicNumber: Int): Props = Props(new DemoActor(magicNumber)) 
} 

问题是什么指明工厂道具方法等之间的区别:

object DemoActor { 
    def props(magicNumber: Int): Props = Props(classOf[DemoActor], magicNumber) 
} 

如果你错过了,所不同的是对道具构造函数的说法:

new DemoActor(magicNumber) 

VS

classOf[DemoActor], magicNumber 

,从同样的阿卡文档页面位进一步向上在Props section,它使用Props(classOf[ActorWithArgs], "arg1")时也提到: “一个匹配的构造的存在施工道具对象的过程中被验证,从而导致如果没有找到或找到多个匹配的构造函数,则返回IllegalArgumentEception。“

这是很好的,不是吗?!?....

回答

10

这很好,不是吗?!?....

是的,但即使是如果在编译期间可以捕获错误,那么效果会更好。直接调用构造函数的优点是编译器会捕获没有匹配构造函数的问题,而不是在运行时抛出异常。

有关Propsapply方法的一个有趣的事情是,当你写:立即在创建道具实例

Props(new DemoActor(magicNumber)) 

演员的构造不会被调用。通过名称而不是通过值传递构造函数调用。您可以在Propsapply方法的签名看到这一点:

def apply[T <: Actor](creator: ⇒ T)(implicit arg0: ClassTag[T]): Props 

请注意,在创作者的参数右箭头。这允许创建者构造被推迟,并且可能在远程演员的另一个过程中被执行。

这里的一个潜在危险是如果new操作在范围内关闭并捕获一个不打算序列化或不可序列化的值,从而使Props对象也不可序列化。这就是为什么文档建议在参与者的伴随对象中这样做 - 以最小化关闭不打算序列化的数据的风​​险。

+0

非常感谢您的回答。你给了我一个哦,我看到的时刻,并与阿卡更有信心。感谢您指出道具上的应用签名将作为名称进行操作。我原本以为在性能上避免了'classOf [DemoActor]'(因为我以前在Java类查找方面的经验很昂贵)。编译时错误提升在我的情况是好的,当我真的需要它时,我会为特殊场合留下* dynamic *查找。再次感谢您的帮助。 – neurozen 2014-11-05 04:27:49

+1

一个名为call-by的参数在运行时是'scala.Function0'。 Akka如何序列化函数对象? – 2015-01-26 14:22:38

+0

我并不完全确定,但我相信字节码实际上是被转移,然后加载到远程端。它只在没有由不可序列化的闭包捕获的上下文时才起作用。如果你真的想知道它是如何完成的,我会建议把它作为自己的问题。 – 2015-01-26 15:26:23