2013-08-27 22 views
10

Tworzę wiele cech, które rozszerzają Aktora. Następnie chcę stworzyć klasę aktorów, która wykorzystuje niektóre z tych cech. Jednak nie jestem pewien, jak połączyć metody odbierania ze wszystkimi cechami w metodzie odbierania klasy Aktor.układanie wielu cech w akka Aktorzy

Cechy:

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

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

aktor:

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

Teraz, jeśli wyślę "r" i "s" do FinalActor idzie tylko w ServerLocatorTrait - który jest ostatnią cechą dodał. Więc sposób to działa w tej chwili jest to, że uważa, że ​​bardzo ostatnia cecha dodał, więc w tym przypadku ServerLocatorTrait

Pytanie:
Jak połączyć metody odbioru ze wszystkich cech w FinalActor?

PS - Widziałem aktorów z react przykład: http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/ ale to nie to co muszę

+0

możliwe duplikat [Scala wieżowych cecha wzór z aktorów Akka] (http://stackoverflow.com/questions/18124643/scala-stackable-trait-pattern-with-akka-actors) – cmbaxter

+0

@cmbaxter Nie widzę, jak to może być duplikat tego. Może to OP może wykorzystać to, co wybrałem jako rozwiązanie. – Adrian

Odpowiedz

17

Nie jestem pewien, czy można połączyć otrzymać metod, ponieważ wiązałoby nazywając Super super do uzyskaj metodę ServiceRegistration za pomocą metody ServiceRegistration. Byłoby to również bardzo mylące.

Innym sposobem byłoby podanie różnych nazw w metodzie receive.

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

} 

Można nadal używać Ci początkowe podejście, ale musisz Łańcuch super.receive dla każdego mieszane cechy.

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 

To drugie rozwiązanie wydaje mi się dość brzydkie.

Proszę patrz poniższy link do bardziej szczegółowej dyskusji na ten temat:

Extending Actors using PartialFunction chaining

+0

Podoba mi się twoje pierwsze rozwiązanie i myślę, że będę z niego korzystał (pokazuje więcej tego, co się dzieje); Początkowo szukałem czegoś takiego jak twoje drugie rozwiązanie. – Adrian

+0

Twoje cechy mogą być zadeklarowane jako: cecha ServerLocatorTrait {this: Actor => ....}, ponieważ same nie są aktorami rzeczywistymi. Przy takiej składni powiesz: "Ta cecha zostanie wymieszana z aktorem". –