2013-06-27 5 views
1

я должен актерских классов который похож на эту форму:уменьшить дублирование кода путем абстрагирования смешивания класса

class ActorSupervisorOne(prop: Prop) extends Actor { 
    val dbSuper = context.actorOf(prop) 
    val subActor = context.actorOf(Props(new SubActorClass(dbSuper) with **SomeHandlersOne**)) 

    def receive = { 
    case msg => 
     subActor forward msg 
    } 
} 

class ActorSupervisorTwo(prop: Prop) extends Actor { 
    val dbSuper = context.actorOf(prop) 
    val subActor = context.actorOf(Props(new SubActorClass(dbSuper) with **SomeHandlersTwo**)) 

    def receive = { 
    case msg => 
     subActor forward msg 
    } 
} 

Единственное различие между ними в смешении черты. Аннотация его с параметром типа или абстрактным членом типа не будет работать. Я пробовал следующее решение, но это выглядит некрасиво и еще дублирования кода:

abstract class Super extends Actor { 
    _: { 
    val handler: Props 
    } => 

    lazy val actor = context.actorOf(handler) 

    def receive = { 
    case msg => 
     actor forward msg 
    } 

} 

class ActorSupervisorOne(val dbSuper: ActorRef) extends Super { 
    val handler = Props(new SubActorClass(dbSuper) with SomeHandlersOne) 
    actor 
} 

class ActorSupervisorTwo(val dbSuper: ActorRef) extends Super { 
    val handler = Props(new SubActorClass(dbSuper) with SomeHandlersTwo) 
    actor 
} 

Но в этом случае я должен позвонить actor правильно инициализировать его или он не будет работать. Есть ли другое решение, как это можно уменьшить?

ответ

2

Возможно, вы можете использовать отражение, чтобы выбрать SomeHandlersXYZ во время выполнения, но если вы не хотите прибегать к отражению, я не думаю, что есть способ добиться того, чего вы хотите, по крайней мере, для дублирования субкомпонента код (см. this answer). Вы можете сделать это следующим образом (эскизного), где в основном проходить в функции фабрики:

class ActorSupervisor(prop: Prop, getSubActor: Actor => SubActorClass) extends Actor { 
    val dbSuper = context.actorOf(prop) 
    val subActor = context.actorOf(Props(getSubActor(dbSuper))) 

    def receive = { 
    case msg => 
     subActor forward msg 
    } 
} 

val asOne = new ActorSupervisor(..., a => new SubActorClass(a) with SomeHandlersOne) 
val asTwo = new ActorSupervisor(..., a => new SubActorClass(a) with SomeHandlersTwo) 
0

Что об этом решении:

class ActorSupervisor(subActor: => Actor) extends Actor { 
    val actor = context.actorOf(Props(statsProps)) 
    def receive = { 
    case msg => 
     actor forward msg 
    } 
} 

, а затем, как и в Malte Schwerhoff вы можете создать новый актер, как это:

val first = new ActorSupervisor(new SubActorClass(...) with SomeHandlersOne) 

Я думаю, что более элегантный colution может быть achived с макросами, но я не очень хорошо на них

0

Вы можете пройти шайбу на onReceive.

class ClassMixed(params: Options*) 
    extends BaseClass(params: _*) 
    with Mixin { 

    override def receive = 
    mixinReceive orElse receive 
} 

, где Mixin имеет метод, называемый mixinReceive и BaseClass переопределяет получают