2015-02-01 2 views
2

Я использую торт шаблон в Scala 2.10, чтобы придать необходимую черту моего актера acording до некоторой BUSSINESS логики:Как обойти типа стирания на Акку получить метод

У меня есть несколько типов F События:

sealed abstract class Event(val timeStamp:Long) 
    case class StudentEvent(override val timeStamp:Long, studentId:Long) extends Event(timeStamp:Long) 
    case class TeacherEvent(override val timeStamp:Long, teacherIdId:Long) extends Event(timeStamp:Long) 

Теперь у меня есть черты, которые реализуют действие для каждого типа события:

Аннотация:

trait Action[T <: Event] { 
    def act[T](event:T):Unit 
} 

И два impls:

trait StudentAction extends Action[StudentEvent]{ 
    override def act[StudentEvent](event:StudentEvent):Unit = println(event) 
} 

и

trait TeacherAction extends Action[TeacherEvent]{ 
    override def act[TeacherEvent](event:TeacherEvent):Unit = println(event) 
} 

Теперь мой актер:

class ActionActor[T <: Event] extends Actor{ 
    self:Action[T]=> 

    override def receive= { 
    case msg: T => act(msg) 
    case _ => println("Unknown Type") 
    } 
} 

И я инъекционные необходимую черту так:

val actionActor = system.actorOf(Props(new ActionActor[StudentEvent] with StudentAction)) 
actionActor ! StudentEvent(1111L,222L) 

На компиляции я Ошибка получения:

Warning:(14, 14) abstract type pattern T is unchecked since it is eliminated by erasure 
    case msg:T => act(msg) 
     ^

Я знаю, что как-то мне нужно использовать TypeTag, но я не смог понять, как это сделать.

Пожалуйста, помогите.

Update:

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

Я хочу реализовать бизнес-логику для каждого события в отдельном признаке, потому что, поскольку смешивание всех 10 функций обработчика событий даст мне несколько сотен (если не тысяч) строк кода.

Я не хочу создавать разные типы персонажей для каждого события. Например:

class Event1Actor extend Actor{ 
    def receive ={ 
    case Event1(e) => //event1 Business Logic 
    } 
} 

class Event2Actor extend Actor{ 
    def receive ={ 
    case Event2(e) => //event2 Business Logic 
    } 
} 

и тот же Event3Actor, Event4Actor и т.д ....

Такой код кажется уродливым ко мне, потому что мне нужно для реализации бизнес логики внутри каждого актера.

Я ищу какое-то общее решение на основе шаблона проектирования, например, шаблон стратегии.

ответ

7

Во-первых, я хотел бы предложить определение ваших событий, как:

sealed trait Event { def timeStamp: Long } 
case class StudentEvent(timeStamp: Long, studentId: Long) 
    extends Event 
case class TeacherEvent(timeStamp: Long, teacherId: Long) 
    extends Event 

Это стандартная кодировка для алгебраических типов данных.

Во-вторых, этот бизнес, в котором вы используете самонавод, кажется мне очень запутанным. Несомненно, тот же объект не должен быть «актером» и «действием»? Почему бы не использовать композицию здесь вместо наследования? (Кажется, вы просто бросаете функции Scala вместе. Таким образом, общий совет здесь будет: замедлить ход.)

Но для решения вашего основного вопроса, я думаю, вы принципиально ошибаетесь. Почти каждый раз, когда вы заканчиваете тем, что боитесь головами с типом стирания и/или TypeTag, это признак того, что ваш дизайн испорчен, и вы должны делать резервную копию и переосмысливать - если вы не узнаете, что делаете.

В любом случае, вы не сможете получить Akka, чтобы прикрепить к своим сообщениям TypeTag. Акка просто не работает. (Была предпринята серия усилий по добавлению «типизированных актеров» или «типизированных каналов» в Akka, и вы можете посмотреть их вверх, но это, вероятно, будет излишним в вашем случае использования, если вы не уверены, что это не так.)

Какова основная архитектурная проблема, которую вы пытаетесь решить здесь? Что мотивировало этот дизайн?

Отъезд Composing trait behavior in Scala in an Akka receive method, похоже, похоже, и после переваривания его, я думаю, вы сможете лучше решить, что делать дальше.

+0

Благодарим вас за ответ, см. Мое обновление. –

+0

Ваш новый вопрос очень убедительный. Я предлагаю задать его как новый, отдельный вопрос. –

+1

Новый вопрос Danny теперь находится здесь: http://stackoverflow.com/q/28341337/86485 –

Смежные вопросы