2014-11-03 174 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