2010-03-09 8 views
8

Ich habe eine Listenable/Listener-Eigenschaft implementiert, die zu Actors hinzugefügt werden kann. Ich frage mich, ob es möglich ist, diese Art von Merkmal an einen Schauspieler anhängen, ohne dass es explizit die listenerHandler Methode aufrufen muss?Komponieren von Schauspielern

Auch ich hatte erwartet, diese Funktionalität in der Akka-Bibliothek zu finden. Fehle ich etwas oder gibt es einen Grund, dass Akka das nicht mit einschließt?

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()) 
    } 
} 

Antwort

5

Warum erstreckt sich nicht Actor direkt, oder wenn Sie nicht-Schauspieler wollen auch Listen sein, eine ListenableActor erstellen, die Schauspieler mit Listen erstreckt?

Sie würden dann receive in Actor außer Kraft setzen, wie Sie oben getan haben (außer Sie möchten super.receive auch anrufen, möchten Sie nicht? - Sie möchten nur die Funktion ändern, die übergeben wird).

+0

Nun ist das die Sache, die ich in beiden Fällen würde sich daran zu erinnern eit zu nennen ihr super.receive oder * listenerHanlder *. Ich habe mich gefragt, ob es einen Mechanismus in Scala im Allgemeinen oder in einer der Actor-Bibliotheken gab, der dem Darsteller erlaubte, nichts zu tun, außer zu sagen: * mit Listenable * –

+0

Aber Sie müssten nur 'extends ListenableActor' sagen anstelle von 'extends Actor'; in "ListenableActor" hättest du 'receive' (und vermutlich' receiveWithin') bereits überschrieben. Siehe auch Daniels Antwort. –

2

Ich schlage vor, Sie erweitern Actor und verwenden Sie eine abstract override.

0

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) 
     } 
    } 
} 
+0

Sie haben gerade eine 'Eigenschaft' in eine' Klasse' umgewandelt ... –