Я реализовал Приятную для слуха черту / черту Слушателя, которая может быть добавлена к Агентам. Я задаюсь вопросом, возможно ли присоединить этот стиль черты к агенту без него имеющий необходимость явно назвать listenerHandler метод?
Также я ожидал находить эту функциональность в библиотеке 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
напрямую, или если вы хотите, чтобы не-актеры также были Listenable, создайте ListenableActor, который расширяет Actor с помощью Listenable?
Затем вы должны переопределить receive
в Актере, как вы это делали выше (за исключением того, что вы также хотите вызвать super.receive
, не так ли? - вы просто хотите изменить переданную функцию).
Я предлагаю вам расширить Actor и использовать абстрактное переопределение
.
Вот решение (модифицированная версия примера из Beginning 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)
}
}
}
Почему я не видел этот вопрос раньше, ну, лучше поздно, чем никогда: