2012-05-23 18 views
3

我正在用scala來完成我的第一步。在使用Actor時何處定義案例類

我已經創建了一個PhotosLoaderActor,它將負責下載圖像並將其保存到緩存中。要做到這一點,我將有一個CacheActor和一個DownloadActor

PhotosLoaderActor有這樣的:

override def act() { 
    loop { 
    react { 
     case (caller : Actor, photoToLoad:String) => { // bla bla } 

正好我可以用case classes使用這樣的事情:

case class LoadImage(caller: Actor, photoToLoad: String) 
override def act() { 
    loop { 
    react { 
     case LoadImage(caller, photoToLoad) => { // bla bla } 

我的問題是:

我應該在哪裏定義case classes ? 如果我從另一個包中調用PhotosLoaderActor,則導入演員還會導入case classes?最佳做法是什麼?

回答

10

我已經嘗試了幾種不同的方法,並決定將所有相關消息放入一個對象中,通常名稱類似於XyzProtocol。

例如:

object PhotoProtocol { 
    case class LoadImage(caller: Actor, photoToLoad: String) 
    case class UpdateCache(photoToLoad: String, photo: Photo) 
    case object ClearCache 
} 

我喜歡這種方法的幾個原因:

  1. 掃描含包,無論是在一個IDE或ScalaDoc,僅示出了1個或幾個XyzProtocol而不是散佈數十條消息。

  2. 如果處理消息所需的參與者數量隨時間發生變化(例如,將參與者池或間接引入其他參與者子樹),則不會影響消息。

  3. 沒有意外捕獲actor實例,就像在定義actor類中的case類時那樣。這種意外的捕獲足以讓我永遠不會在演員類中定義案例類。

注意:如果該消息是純粹動作者(例如,內部信號通過自身發送到本身)的內部實現細節,我定義在演員類的同伴對象的消息。

PS。我也建議從標準庫演員轉到阿卡。 Akka將被添加到Scala 2.10發行版中。

1

我經常在使用它們的actor上面定義它們。或者,如果多個參與者在相同案例中匹配,則專門用於這些案例類。

package org.numbers 
import akka.actor.Actor 

sealed trait Numbers 
case class Even(n: Int) extends Numbers 
case class Odd(n: Int) extends Numbers 

class NumberActor extends Actor { 
    def receive = { 
    case Even(n) => doEven(n) 
    case Odd(n) => doOdd(n) 
    } 

    def doEven = ... 
    def doOdd = ... 
} 

使用akka而不是scala actors,但無論如何。這樣,導入包含actor的包也將導入可發送給該actor的消息。如果案例類被定義在演員的「內部」,那麼他們將不會被其他想要向該演員發送消息的類使用。

1

如果Actor是一個單例對象,那麼我可能會把它放入對象本身。

相關問題