Java で拡張可能な駆動型アーキテクチャを実装しようとしています。残念ながら、完全にタイプセーフにすることはできません。以下は私がしたことです。
まず、イベントを定義します。拡張するのはほとんど空のクラスです。
public abstract class Event {
public final Class<? extends Event> getEventType() {
return this.getClass();
}
}
そしてリスナー:
public interface Listener<T extends Event> {
Class<T> getEventType();
void onEvent(T event);
}
ここまでは順調ですね。しかし、イベント ディスパッチャーを実装しようとすると、行き詰まりました。
public class EventDispatcher {
private Map<Class<? extends Event>, Collection<Listener>> listenersDict = new HashMap<>();
public void registerListener(Listener listener) {
Class<? extends Event> eventType = listener.getEventType();
Collection<Listener> listeners = listenersDict.get(eventType);
if(listeners == null) {
listeners = new ArrayList<>();
listenersDict.put(eventType, listeners);
}
listeners.add(listener);
}
public void dispatch(Event event) {
Class<? extend Event> eventType = event.getEventType();
Collection<Listener> listeners = listenersDict.get(eventType);
if(listeners != null) {
for(Listener listener : listeners) {
@SuppressWarnings("unchecked") // Necessary Evil?
listener.onEvent(event);
}
}
}
}
ご覧のとおり、使用する必要があります@SuppressWarnings
。私は理解できるあらゆる方法を試しましたが、いずれかでregisterListener
あり、dispatch
常にタイプセーフではありません。(またはに変更Listener
すると機能しません。私は本当に試しました。)Listener<Event>
Listener<? extends Event>
EventDispatcher
安全でないコードなしで、同じ柔軟性 (拡張可能なイベントとリスナー、異なるリスナーを処理する単一のディスパッチャー) でアーキテクチャを実装することは可能ですか?