Вопрос
Я реализовал свойство Listenable / Слушатель, которое может быть добавлено к актерам.Мне интересно, возможно ли прикрепить этот стиль признака к актеру без необходимости явного вызова Манипулятор для прослушивания способ?
Также я ожидал найти эту функциональность в библиотеке Akka.Я что-то упускаю или есть какая-то причина, по которой Akka не включила бы это?
trait Listenable { this: Actor =>
private var listeners: List[Actor] = Nil
protected def listenerHandler: PartialFunction[Any, Unit] = {
case AddListener(who) => listeners = who :: listeners
}
protected def notifyListeners(event: Any) = {
listeners.foreach(_.send(event))
}
}
class SomeActor extends Actor with Listenable
{
def receive = listenerHandler orElse {
case Start => notifyListeners(Started())
case Stop => notifyListeners(Stopped())
}
}
Решение
Почему бы не расширить Actor
напрямую, или, если вы хотите, чтобы неакторы также были доступны для прослушивания, создайте ListenableActor, который расширяет Actor с помощью Listenable?
Тогда вы бы переопределили receive
в Actor, как вы сделали выше (за исключением того, что вы хотели бы вызвать super.receive
кроме того, не так ли?--вы бы просто хотели изменить переданную функцию).
Другие советы
Я предлагаю вам расширить Actor и использовать abstract override
.
Почему я раньше не сталкивался с этим вопросом, э-э-э, ну, лучше поздно, чем никогда:
Вот решение (модифицированная версия примера из начала Scala):
import se.scalablesolutions.akka.actor.Actor
case class AddListener(who: Actor)
case class RemoveListener(who: Actor)
class ListenableActor extends Actor {
private var listeners: List[Actor] = Nil
def receive = {
case AddListener(who) => listeners ::= who
case RemoveListener(who) => listeners.filter(_ ne who)
}
protected def notifyListeners(event: Any) = {
listeners.foreach(_.send(event))
}
}
class ImplementingActor extends ListenableActor {
override def receive = {
super.receive orElse {
case Message(content) => println(content)
}
}
}
Для этого в Akka есть встроенная поддержка: https://github.com/jboner/akka/blob/release-1.2/akka-actor/src/main/scala/akka/routing/Listeners.scala