2012-05-23 5 views
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? Какая практика?

ответ

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. Нет случайного захвата экземпляра актера, как это бывает при определении классов случаев внутри класса актера. Этот случайный захват является достаточным основанием для того, чтобы я никогда не определял классы case внутри класса актера.

Примечание: если сообщение является исключительно внутренним деталь реализации актера (например, внутренний сигнал, посылаемый себя сам по себе), я определить сообщение в сопровождающем объект класса актера.

PS. Я также предлагаю переехать в Акку из стандартных участников библиотеки. Akka будет добавлен в дистрибутив Scala 2.10.

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, но в любом случае. Таким образом, импорт пакета, содержащего актера, также будет импортировать сообщения, которые могут быть отправлены этому актеру. Если классы case определены «внутри» актера, они не будут доступны другим классам, которые хотят отправлять сообщения этому актеру.

1

Если актер - это одноэлементный объект, я бы, вероятно, поместил его внутри самого объекта.

Смежные вопросы