2013-04-11 49 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