Как правильно использовать актеров акка в скале

Я относительно новичок в представлениях об актерах, и мне было интересно, могу ли я получить некоторую критику в отношении того, что я делаю. Для части проекта мне нужен актер, который сообщает собравшимся актерам время. Актеры-слушатели должны иметь возможность быть добавленными к этому актеру.

В настоящее время у меня есть это:

import akka.actor.Actor;

import akka.actor.ActorRef;
import com.github.nscala_time.time.Imports._;

class TimeManager extends Actor {
  var actors:List[ActorRef] = List();
  def receive = {
    case AdvanceTime() => actors foreach (_ ! DateTime.now)
    case AddListener(x) => actors =  x :: actors
  }
}

Есть ли способ, которым я могу удалить состояние (актеры var) из этого кода, чтобы сделать его более функциональным?

 Simon Todd03 июл. 2013 г., 13:36
Лучше всего иметь только одного родителя на каждого ребенка. Это означает, что вы должны избегать передачи Actors (и в этом случае любых изменяемых объектов) в качестве сообщений другим акторам. Попробуйте структурировать систему акторов как иерархию - это позволяет лучше контролировать и контролировать систему.

Ответы на вопрос(2)

Сильной стороной Scala является ее гибрид OO и функционального программирования.не нужно ненавидетьvar, если вы это сделаете, вам может понадобиться выбрать Haskell.

В вашем случае, я думаю, единственное, что вам нужно изменить, это сделатьactors какprivate

Решение Вопроса

Вы можете'удалить состояние сTimeManager должен содержать список актеров.

Вы могли бы скрыть это:

class TimeManager extends Actor {
  def receive = getBehavior(Nil)
  def getBehavior(actors: List[ActorRef]): Receive = {
    case AdvanceTime() => actors foreach (_ ! DateTime.now)
    case AddListener(x) => context become getBehavior(x :: actors)
  }
}
 アレックス07 дек. 2013 г., 10:07
оно может'не принимать никаких аргументов - почему? >> - потому что мы можем отправить только сообщение, мы можемт звонитеПолучать" непосредственно предоставляя аргументы к нему.
 senia07 дек. 2013 г., 10:11
@ Алекс: типgetBehavior _ являетсяList[ActorRef] => Receive, Так что вы можете'т перейти кbecome, ТипgetBehavior(x :: actors) является .Receive
 アレックス07 дек. 2013 г., 08:31
Я пытаюсь понять это.getBehavior имеет тип возвратаReceive, Следовательно, этоМожно'не принимать никаких аргументов когда мы звонимcontext become getBehavior потому что сообщения, отправляемые актеру, обрабатываются либо сreceive и какой-то метод, который "становиться" - методы, которые нене принимать никаких аргументов. Правильный? Так что же даст аргумент?getBehavior
 Madoc20 июн. 2013 г., 11:44
Ух, интересное применение! Я покупалbecome
 senia07 дек. 2013 г., 09:43
@Alex:it can't take any arguments - Зачем?Receive на самом делеPartialFunction, такgetBehavior принимаетList в качестве параметра и создаетPartialFunction, И этоPartialFunction используетсяActor обрабатывать сообщения. методreceive обеспечивает поведение по умолчанию. Послеbecome методreceive больше не будет использоваться.
 アレックス07 дек. 2013 г., 10:06
Мне трудно понять, что делает. Когда я звонюстать (MyFunc)», это означает, чтовсе сообщения будут отправляться наmyFunc с тех пор правильно? <<
 senia07 дек. 2013 г., 10:09
@ Алекс: Да, этоправильно. Но в методе есть второй аргумент:becomediscardOld: Boolean = true, Вы можете указать это какfalse и использовать.unbecome

Ваш ответ на вопрос