使用Actors时在何处定义案例类

时间:2012-05-23 00:24:21

标签: scala actor

我的第一步是scala

我创建了一个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,导入actor还会导入case classes?哪种是最佳做法?

3 个答案:

答案 0 :(得分:11)

我尝试了一些不同的方法,并决定将所有相关的消息放入一个对象,通常命名为XyzProtocol。

例如:

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

我喜欢这种方法有几个原因:

  1. 在IDE或ScalaDoc中扫描包含的包只显示一个或几个XyzProtocol对象,而不是散落着几十条消息。

  2. 如果处理消息所需的参与者数量随时间而变化(例如,引入actor池或间接到另一个actor子树),则消息不会受到影响。

  3. 没有意外捕获actor实例,就像在actor类中定义case类一样。这种意外捕获足以让我永远不会在actor类中定义case类。

  4. 注意:如果消息纯粹是actor的内部实现细节(例如,自身发送给自身的内部信号),我在actor类的伴随对象中定义消息。

    PS。我还建议从标准图书馆演员那里搬到Akka。 Akka将被添加到Scala 2.10发行版中。

答案 1 :(得分:1)

我经常在使用它们的actor上面定义它们。或者在专用于这些案例类的文件中,如果多个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 actor,但无论如何。这样,导入包含actor的包也将导入可以发送给该actor的消息。如果案例类是在actor的“内部”定义的,那么它们将无法用于其他想要向该actor发送消息的类。

答案 2 :(得分:1)

如果Actor是一个单例对象,那么我可能会将它放在对象本身内。