Bis jetzt haben wir auf Nachrichten immer mit receive reagiert.
Manchmal möchten wir jedoch auf Nachrichten unterschiedlich reagieren. Eine Möglichkeit
das zu Realisieren ist, in den einzelnen cases entsprechende Kontrollstrukturen
einzubauen.
Wir brauchen sicher nicht viel Fantasie, um uns vorzustellen, wie schnell die receive
Methode unübersichtlich wird und aus Spaghetti-Code besteht.
Abhilfe schaffen hier die Methoden become und unbecom des zugehörigen
ActorContext. Die Methode become erwartet als Argument eine Methode (Funktion),
welche mit der receive Methode kompatibel ist. Von diesem Zeitpunkt an werden
die zu bearbeitenden Nachrichten von der neuen Methode abgearbeitet. Auch in der neuen
Bearbeitungsmethode können wir die aktuelle Bearbeitungsmethode mit become
neu zuweisen.
Möchten wir den initialen Zustand wieder herstellen, können wir die unbecome
Methode des ActorContext aufrufen. Diese Methode stellt den ursprünglichen (initialen)
Zustand wieder her, unabhängig davon, wie oft das Verhalten mit become verändert
wurde.
Das nachfolgende Beispiel zeigt die Verwendung von become und unbecome.
import akka.actor._
case class SimpleMessage(s: String)
case object DoBecomeNewReceiver
case object DoUnbecome
object MyApplication {
def main(args: Array[String]) {
val system = ActorSystem("Main")
val ac = system.actorOf(Props(classOf[MyActor]))
ac ! SimpleMessage("Hi!")
ac ! DoBecomeNewReceiver
ac ! SimpleMessage("Ho!")
ac ! DoBecomeNewReceiver
ac ! SimpleMessage("Jo.")
ac ! DoUnbecome
ac ! SimpleMessage("How are you?")
Thread.sleep(1000)
sys.exit(0)
}
}
class MyActor extends Actor {
def receive = {
case SimpleMessage(s) => println("Initial: "+s)
case DoBecomeNewReceiver => context become receiveA
}
def receiveA: Receive = {
case SimpleMessage(s) => println("receiveA: "+s)
case DoBecomeNewReceiver => context become receiveB
case DoUnbecome => context unbecome
}
def receiveB: Receive = {
case SimpleMessage(s) => println("receiveB: "+s)
case DoUnbecome => context unbecome
}
}
Die Ausführung des Programms führt zu folgender Ausgabe auf der Systemausgabe:
Initial: Hi!
receiveA: Ho!
receiveB: Jo.
Initial: How are you?