Укладка нескольких черт в акк Актеры

Я создаю несколько черт, которые расширяют Actor. Затем я хочу создать класс актера, который использует некоторые из этих признаков. Тем не менее, я не уверен, как объединить методы получения от всех признаков метода получения класса Actor.

Черты:

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

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

Актер:

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

Теперь, если я отправляю "r" и "s" в FinalActor, он идет только в ServerLocatorTrait - это последняя добавленная черта. Так вот как это работает сейчас, это то, что он считает супер последним добавленным признаком, поэтому в этом случае ServerLocatorTrait

Вопрос:
Как объединить методы приема со всеми чертами в FinalActor?

PS - Я видел актеров с примером react: http://www.kotancode.com/2011/07/19/traits-multiple-inheritance-and-actors-in-scala/ но это не то, что мне нужно

Ответ 1

Я не уверен, что вы можете комбинировать методы приема, поскольку это потребует вызова супер супер для получения метода ServiceRegistration receive. Это также было бы очень запутанным.

Другим способом было бы дать разные имена методу 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()

}

Вы все равно можете использовать свой первоначальный подход, но вы должны привязать super.receive к каждому смешанному признаку.

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

Последнее решение выглядит довольно уродливо для меня.

Для более подробного обсуждения темы см. приведенную ниже ссылку:

Расширение участников с использованием цепочки PartialFunction