Frage
Ich habe ein hörbares/Hörer -Merkmal implementiert, das den Schauspielern hinzugefügt werden kann. Ich frage mich, ob es möglich ist, diesen Merkmalsstil einem Schauspieler zu verbinden, ohne dass er das ausdrücklich anrufen muss Hörerhandler Methode?
Ich hatte auch erwartet, diese Funktionalität in der Akka -Bibliothek zu finden. Vermisse ich etwas oder gibt es einen Grund, warum Akka dies nicht aufnehmen würde?
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())
}
}
Lösung
Warum nicht ausdehnen Actor
Direkt oder wenn Sie möchten, dass Nicht-Schauspieler auch hörbar sind, erstellen Sie einen ListenablesActor, der den Schauspieler mit hörbar erweitert?
Sie würden dann überschreiben receive
In Schauspieler wie oben (außer Sie möchten anrufen möchten super.receive
Würden Sie es auch nicht?-Sie möchten nur die Funktion ändern, die übergeben wird).
Andere Tipps
Ich schlage vor, Sie erweitern den Schauspieler und verwenden eine abstract override
.
Warum habe ich diese Frage noch nie gesehen, ähm, besser, spät spät als nie:
Hier ist eine Lösung (eine modifizierte Version des Beispiels von Anfang 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)
}
}
}
In Akka gibt es eingebaute Unterstützung dafür: https://github.com/jboner/akka/blob/release-1.2/akka-actor/src/main/scala/akka/routing/listeners.scala