2011-12-20 33 views
7

ben o zaman her biri için olay işleyicileri uygulayan tek sınıf yapabilirim nasıl buOverloading jenerik olay işleyicileri

trait Event { 

} 
class InventoryItemDeactivated(val id: UUID) extends Event; 

class InventoryItemCreated(val id: UUID, val name: String) extends Event; 

gibi etkinlik türü en aşağıdaki genel olay işleyicisi

trait Handles[E <: Event] { 
    def handle(event: E) 
} 

tanımlarsanız bu olayların Denedim: Ancak Scala, bir özelliğin iki kez miras alınamayacağından şikayetçidir.

Bu, bir çözümde ipuçları veren bu answer buldum, ancak birden çok sınıf (her işleyici için bir tane) gerektirir. Bu gerçekten tek yol mu yoksa tek bir sınıfın birden çok genel olay işleyicisi (yani vaka sınıflarını, tezahürleri veya başka bir süslü yapı kullanarak) yapmak için kullanabileceğim başka bir Scala yapısı var mı? Eğer bakıyor gibi görünüyor

cevap

11

Ben Event bir ADT yapma ve tip Event bir parametreyi kabul etmek kolu tanımlayarak hariç tek sınıfı (bunu yapmak için bir yol bilmiyorum. Ama bu typesafety tür uzakta alacaktı için).

Bunun yerine tip sınıfı desen kullanmayı öneririm.

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

iki ayrı handle yöntemlerin avantajı nedir?

def handle(rawEvent: Event) = rawEvent match { 
    case e: InventoryItemCreated => ... 
    case e: InventoryItemDeactivated => ... 
} 
İlgili konular