Перегрузка общих обработчиков событий в Scala
Если я определяю следующий общий обработчик событий
trait Handles[E <: Event] {
def handle(event: E)
}
с типом события, подобным этому
trait Event {
}
class InventoryItemDeactivated(val id: UUID) extends Event;
class InventoryItemCreated(val id: UUID, val name: String) extends Event;
как мне сделать один класс, который реализует обработчики событий для каждого из этих событий? Я пробовал:
class InventoryListView extends Handles[InventoryItemCreated] with Handles[InventoryItemDeactivated] {
def handle(event: InventoryItemCreated) = {
}
def handle(event: InventoryItemDeactivated) = {
}
}
но Scala жалуется, что черта не может быть унаследована дважды.
Я нашел этот ответ, который намекает на решение, но он швы требует нескольких классов (по одному для каждого обработчика). Это действительно единственный способ или есть какая-то другая конструкция Scala, которую я могу использовать, чтобы один класс реализовал несколько общих обработчиков событий (например, используя классы case, манифесты или какую-либо другую причудливую конструкцию).
Ответы
Ответ 1
Я не знаю, как это сделать в одном классе (за исключением того, что создав Event
ADT и определяя дескриптор, чтобы принять параметр типа Event
. Но это уберет вид типов, который вам кажется для поиска).
Я бы предложил вместо этого использовать шаблон типа.
trait Handles[-A, -E <: Event] {
def handle(a: A, event: E)
}
trait Event {
...
}
class InventoryItemDeactivation(val id: UUID) extends Event
class InventoryItemCreation(val id: UUID, val name: String) extends Event
class InventoryListView {
...
}
implicit object InventoryListViewHandlesItemCreation extends
Handles[InventoryListView, InventoryItemCreation] = {
def handle(v: InventoryListView, e: InventoryItemCreation) = {
...
}
}
implicit object InventoryListViewHandlesItemDeactivation extends
Handles[InventoryListView, InventoryItemDeactivation] = {
def handle(v: InventoryListView, e: InventoryItemDeactivation) = {
...
}
}
def someMethod[A, E <: Event](a: A, e: E)
(implicit ev: InventoryListView Handles InventoryItemCreation) = {
ev.handle(a, e)
...
}
Ответ 2
В чем преимущество двух отдельных методов handle
?
def handle(rawEvent: Event) = rawEvent match {
case e: InventoryItemCreated => ...
case e: InventoryItemDeactivated => ...
}