2011-12-20 4 views
7

Если я определяю следующее общий обработчик событийПерегрузка общих обработчиков событий в 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) = { 

    } 
    } 

но Скала жалуется, что черта не может быть унаследована дважды.

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

ответ

11

Я не знаю, как это сделать в одном классе (за исключением того, чтобы сделать 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) 
    ... 
} 
4

Что преимущество двух отдельных handle методов?

def handle(rawEvent: Event) = rawEvent match { 
    case e: InventoryItemCreated => ... 
    case e: InventoryItemDeactivated => ... 
} 
Смежные вопросы