2013-08-27 9 views
10

Ich erstelle mehrere Eigenschaften, die Schauspieler erweitern. Dann möchte ich eine Schauspielerklasse erstellen, die einige dieser Eigenschaften verwendet. Ich bin mir jedoch nicht sicher, wie ich die Empfangsmethoden von allen Merkmalen in der Empfangsmethode der Actor-Klasse kombinieren soll.stapeln mehrere Merkmale in akka Schauspieler

Merkmale:

trait ServerLocatorTrait extends Actor { 
    def receive() = { 
     case "s" => println("I'm server ") 
    } 
    } 

    trait ServiceRegistrationTrait extends Actor { 
    def receive() = { 
     case "r" => println("I'm registration ") 
    } 
    } 

Der Schauspieler:

class FinalActor extends Actor with ServiceRegistrationTrait with ServerLocatorTrait { 
    override def receive = { 
    super.receive orElse ??? <--- what to put here 
    } 
} 

Nun, wenn ich "r" und "s" zu FinalActor senden es nur in ServerLocatorTrait geht - die hinzugefügt der letzte Zug ist. So ist der Weg, dies jetzt funktioniert, ist, dass sie der Auffassung ist Super das letzte Merkmal hinzugefügt, so dass in diesem Fall ServerLocatorTrait

Frage:
Wie kombiniere ich die Züge in FinalActor Methoden von allen erhalten?

PS - Ich habe die Schauspieler mit react Beispiel zu sehen: http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/ aber es ist nicht das, was ich brauche

+0

möglich Duplikat [Scala stapelbaren Charakterzug Muster mit Akka Schauspieler] (http://stackoverflow.com/questions/18124643/scala-stackable-trait-pattern-mit-akka-aktoren) – cmbaxter

+0

@cmbaxter Ich sehe nicht, wie es ein Duplikat davon sein könnte. Aber vielleicht könnte das OP das verwenden, was ich als Lösung gewählt habe. – Adrian

Antwort

17

Ich bin nicht sicher, wenn Sie die Methoden erhalten kombinieren können, denn das ist die Super des rufenden super bedeuten würde Erhalten Sie die ServiceRegistrationreceive Methode. Es wäre auch sehr verwirrend.

Eine andere Möglichkeit wäre, der receive-Methode in den Merkmalen unterschiedliche Namen zu geben.

trait ServerLocatorTrait extends Actor { 
    def handleLocation: Receive = { 
    case "s" => println("I'm server ") 
    } 
} 

trait ServiceRegistrationTrait extends Actor { 
    def handleRegistration: Receive = { 
    case "r" => println("I'm registration ") 
    } 
} 

class FinalActor extends Actor with ServiceRegistrationTrait with ServerLocatorTrait { 
    def receive = handleLocation orElse handleRegistration 
} 

object Main extends App { 

    val sys = ActorSystem() 

    val actor = sys.actorOf(Props(new FinalActor)) 

    actor ! "s" 
    actor ! "r" 

    sys.shutdown() 

} 

Sie können Sie noch ursprüngliche Ansatz verwenden, aber Sie müssen Kette der super.receive für jeden gemischten Zug.

trait IgnoreAll extends Actor { 
    def receive: Receive = Map() 
} 

trait ServerLocatorTrait extends Actor { 
    abstract override def receive = ({ 
    case "s" => println("I'm server ") 
    }: Receive) orElse super.receive 
} 

trait ServiceRegistrationTrait extends Actor { 
    abstract override def receive = ({ 
    case "r" => println("I'm registration ") 
    }: Receive) orElse super.receive 
} 

class FinalActor extends IgnoreAll with ServiceRegistrationTrait with ServerLocatorTrait 

Die letztere Lösung sieht mir ziemlich hässlich.

finden Sie unter den folgenden Link, um eine ausführliche Diskussion über das Thema:

Extending Actors using PartialFunction chaining

+0

Ich mag Ihre erste Lösung und ich denke, ich werde das verwenden (es zeigt mehr von dem, was vor sich geht); Ich suchte zunächst nach etwas wie deiner zweiten Lösung. – Adrian

+0

Ihre Eigenschaften könnten wie folgt deklariert werden: trait ServerLocatorTrait {this: Actor => ....}, weil sie selbst keine eigentlichen Akteure sind. Mit dieser Syntax sagen Sie "Diese Eigenschaft wird in einen Actor gemischt". –

Verwandte Themen