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以正确初始化它,否则它将不起作用。有没有其他解决方案可以减少这种情况?

4

3 回答 3

2

您可能可以使用反射来选择SomeHandlersXYZ运行时,但如果您不想诉诸反射,那么我认为没有一种方法可以在不复制子角色实例化代码的情况下实现您想要的(请参阅此答案我的解释)。您可以通过以下方式(草图)进行操作,基本上传入工厂函数:

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)
于 2013-06-27T08:02:53.647 回答
0

您可以在 onReceive 上传递冰球。

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

  override def receive =
    mixinReceive orElse receive
}

其中 Mixin 有一个名为 mixinReceive 的方法,并且 BaseClass 覆盖了接收

于 2013-06-27T21:27:44.983 回答
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)

我认为使用宏可以实现更优雅的解决方案,但我不擅长它们

于 2013-06-27T08:51:05.957 回答