2013-08-27 28 views
10

Aktör'ü genişleten birden fazla özellik geliştiriyorum. Sonra bu özelliklerden bazılarını kullanan bir aktör sınıfı oluşturmak istiyorum. Ancak, alma yöntemlerini Aktör sınıfının alma yöntemindeki tüm özelliklerden nasıl birleştireceğimi bilmiyorum.akka'da birden çok özellik istifleme Aktörler

Özellikleri:

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

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

Aktör:

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

Şimdi FinalActor için "r" ve "s" gönderirseniz sadece ServerLocatorTrait gider - Son özellik eklendi olduğunu.
nasıl FinalActor tüm özelliklerin gelen yöntemlerini almak birleştirmek mi: Yani bu şu anda Çalışır şekilde SoruServerLocatorTrait

Dolayısıyla bu durumda, süper son özellik eklendi düşündüğü nedir? http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/ ancak bu yöntemler almak birleştirebilirsiniz eğer buna super en süper çağırarak da eklenmesiyle, bu ben,

+0

olası yinelenen http://stackoverflow.com/questions/18124643/scala-stackable-trait-pattern-with-akka-aktörler) – cmbaxter

+0

@cmbaxter Bunun nasıl bir kopyası olabileceğini anlamıyorum. Yine de OP bu çözüm olarak seçtiğim şeyi kullanabilir. – Adrian

cevap

17

emin değilim gerekenleri değil: -

PS I react örnekle aktörler gördüm ServiceRegistration'un receive yöntemini edinin. Aynı zamanda çok kafa karıştırıcı olurdu.

Başka bir yol, özelliklerde receive yöntemine farklı adlar vermektir.

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

} 

Hala size ilk yaklaşımı kullanabilirsiniz, ancak her karma özellik için zincir super.receive gerekir.

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 

İkinci çözüm bana oldukça çirkin görünüyor.

konuda daha ayrıntılı bir tartışma için aşağıdaki linke bakınız:

Extending Actors using PartialFunction chaining

[Akka aktörlerle Scala istiflenebilir özelliği deseni] (içinde
+0

İlk çözümünüzü beğendim ve bunu kullanacağımı düşünüyorum (neler olup bittiğini gösterir); Başlangıçta ikinci çözümün gibi bir şey arıyordum. – Adrian

+0

Özellikleriniz şu şekilde bildirilebilir: tracer ServerLocatorTrait {bu: Oyuncu => ....}, çünkü onlar gerçek aktörler değildir. Bu sözdizimi ile "Bu özellik bir Aktöre karışacaktır" diyorsunuz. –

İlgili konular