通过抽象混合类减少代码重复

时间:2013-06-27 06:53:32

标签: scala inheritance abstraction code-duplication

我必须使用类似于这种形式的actor类:

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来正确初始化它,否则它将无效。还有其他解决办法可以减少这种情况吗?

3 个答案:

答案 0 :(得分:2)

您可以使用反射在运行时选择SomeHandlersXYZ,但如果您不想求助于反射,那么我认为没有办法实现您想要的而不至少重复subactor实例化代码(请参阅我的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)

答案 1 :(得分: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)

我认为用宏可以获得更优雅的色彩,但我不擅长它们

答案 2 :(得分:0)

你可以通过onReceive传递冰球。

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

  override def receive =
    mixinReceive orElse receive
}

其中Mixin有一个名为mixinReceive的方法,而BaseClass覆盖了