3

私は最初の一歩を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、アクターをインポートするとcase classes?もインポートされます。ベストプラクティスはどれですか?

4

3 に答える 3

11

私はいくつかの異なるアプローチを試し、関連するすべてのメッセージをオブジェクト(通常は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. アクタークラス内でケースクラスを定義する場合のように、アクターインスタンスを誤ってキャプチャすることはありません。この偶発的なキャプチャは、アクタークラス内でケースクラスを定義しないのに十分な理由です。

注:メッセージが純粋にアクターの内部実装の詳細である場合(たとえば、それ自体に送信される内部シグナル)、アクタークラスのコンパニオンオブジェクトでメッセージを定義します。

PS。また、標準ライブラリのアクターからAkkaに移行することをお勧めします。AkkaはScala2.10ディストリビューションに追加されます。

于 2012-05-23T02:17:30.183 に答える
1

私はしばしばそれらを使用するアクターの上にそれらを定義します。または、複数のアクターが同じケースで一致する場合は、それらのケースクラス専用のファイルで。

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 = ...
}

Scalaアクターの代わりにakkaを使用しますが、どちらの方法でも使用します。このように、アクターを含むパッケージをインポートすると、そのアクターに送信できるメッセージもインポートされます。ケースクラスがアクターの「内部」で定義されている場合、そのアクターにメッセージを送信したい他のクラスはそれらを使用できません。

于 2012-05-23T01:21:50.007 に答える
1

アクターがシングルトンオブジェクトの場合、おそらくオブジェクト自体の中に入れます。

于 2012-05-23T01:34:41.920 に答える