Tôi đang cố gắng tạo một hệ thống để trả lời các sự kiện xảy ra trong ứng dụng của tôi, tương tự như mẫu Observer. Trong hệ thống của tôi, EventProducer
s sự kiện kích hoạt và EventConsumer
s ứng phó với những sự kiện, và cả hai đều được kết nối thông qua một trung tâm Trung ương:Cần trợ giúp bằng cách sử dụng Java Generics
Đối với thời điểm này, tôi sẽ bỏ qua EventProducer
và tập trung vào EventHub
và EventConsumer
:
interface EventConsumer<E extends Event> {
void respondToEvent(E event);
}
class EventHub {
private HashMap<Class</*event type*/>, HashSet<EventConsumer</*event type*/>>> subscriptions;
public <E extends Event> void fireEvent(E event) {
/* For every consumer in the set corresponding to the event type {
consumer.respondToEvent(event);
} */
}
public <E extends Event> void subscribeToEvent(EventConsumer<E> consumer) {
/* Insert consumer into the set corresponding to E */
}
}
vấn đề nằm ở việc kê khai của HashMap
: tôi muốn để có thể làm điều gì đó như
HashMap<Class<E extends Event>, HashSet<EventConsumer<E>>>
// or
<E extends Event> HashMap<Class<E>, HashSet<EventConsumer<E>>>
Vì vậy mà các EventConsumer
được tham số hóa bởi cùng loại các Class
là, nhưng gần nhất tôi có thể nhận được là
HashMap<Class<? extends Event>, HashSet<EventConsumer<? extends Event>>>
Nhưng sau đó điều này sẽ cho phép những thứ như một HashSet<EventConsumer<MouseClickEvent>>
được gán cho Class<KeyPressEvent>
, giả sử cả KeyPressEvent
và MouseClickEvent
lớp con Event
.
Một vấn đề thứ hai là trong subscribeToEvent
: Tôi cần phải có khả năng lưu trữ cho người tiêu dùng trong các thiết lập chính xác tương ứng với sự kiện của nó, giống như trong
subscriptions.get(E.class).put(consumer)
nhưng tôi không thể có được lớp của E tại thời gian chạy .
Tôi làm cách nào để giải quyết các vấn đề này? Tôi đang đi về điều này một cách sai lầm?
Thực ra, tôi thích cách tiếp cận này. Ban đầu, tôi đã muốn có thể làm một cái gì đó như 'lớp SomeConsumer thực hiện EventConsumer, EventConsumer ', nhưng dường như bạn không thể làm điều đó (mà tôi đoán có ý nghĩa).Có cách nào tôi có thể nhận được một số dạng đa hình 'Event' trên một người tiêu dùng, để tránh một sự chuyển đổi trong' respondToEvent'? Giống như 'void responseToEvent (ClickEvent); void respondToEvent (KeyPressEvent); '? –
@AustinHyde Tôi không biết. Tôi đã chơi đùa với điều đó, nhưng tôi không thể tìm ra cách tốt để làm điều đó mà không tạo ra tất cả sự hỗn loạn của Generics trong 'EventHub'. Bạn cũng nên xem xét khả năng đọc của mã. Ngay cả khi nó hoạt động kém hiệu quả, nếu nó dễ dàng duy trì theo thời gian, tôi nghĩ nó đáng giá (trừ khi bạn đang viết một trò chơi trên máy tính hoặc một công cụ tìm kiếm hoặc thứ gì đó tính bằng mili giây). Đối với tôi, tất cả những generics đó làm cho mã khó đọc và dễ hiểu hơn. – Michael