2011-12-20 25 views
7

Nếu tôi xác định các sự kiện chung xử lý sauxử lý sự kiện chung chung quá tải tại Scala

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

với sự kiện kiểu như thế này

trait Event { 

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

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

làm thế nào để sau đó tạo ra một lớp duy nhất mà thực hiện xử lý sự kiện cho mỗi của những sự kiện này? Tôi đã thử:

class InventoryListView extends Handles[InventoryItemCreated] with Handles[InventoryItemDeactivated] { 
    def handle(event: InventoryItemCreated) = { 

    } 

    def handle(event: InventoryItemDeactivated) = { 

    } 
    } 

nhưng Scala than phiền rằng một đặc điểm không thể được kế thừa hai lần.

Tôi tìm thấy điều này answer gợi ý một giải pháp, nhưng nó ghép nối để yêu cầu nhiều lớp (một cho mỗi trình xử lý). Đây có phải là cách duy nhất hay là có một số cấu trúc Scala khác mà tôi có thể sử dụng để làm cho một lớp đơn lẻ triển khai nhiều trình xử lý sự kiện chung (tức là sử dụng các lớp chữ, biểu hiện hoặc một số cấu trúc ưa thích khác)?

Trả lời

11

Tôi không biết cách nào để làm điều đó trong một lớp (ngoại trừ việc tạo Event một ADT và xác định xử lý để chấp nhận tham số loại Event. Nhưng điều đó sẽ loại bỏ loại an toàn mà bạn dường như đang tìm kiếm cho).

Tôi khuyên bạn nên sử dụng mẫu kiểu lớp thay thế.

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

Lợi thế của hai phương pháp riêng biệt handle là gì?

def handle(rawEvent: Event) = rawEvent match { 
    case e: InventoryItemCreated => ... 
    case e: InventoryItemDeactivated => ... 
} 
Các vấn đề liên quan