gpt4 book ai didi

java - 实现事件驱动架构的类型更安全的方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:09:09 24 4
gpt4 key购买 nike

我正在尝试用 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 .我尝试了所有我能想到的方法,但其中一个 registerListenerdispatch始终是类型不安全的。 (把Listener改成Listener<Event>或者Listener<? extends Event>里面的EventDispatcher都不行,我真的试过了。)

是否可以实现具有相同灵 active (可扩展事件和监听器,处理不同监听器的单个调度程序)但没有不安全代码的架构?

最佳答案

首先,我建议您不要使用类进行比较,而是使用EventType。枚举并改用它,但它很容易替换。

其次,请原谅我使用 java 1.6(注意 <> 语法的替换)。

至于问题,您没有使用 getEventType() Listener 上的方法界面。此外,您不需要接收 T 类型的对象。在onEvent()方法。

大部分更改是对 EventDispatcher 进行的:

public class EventDispatcher {
private Map<Class<? extends Event>, Collection<Listener<? extends Event>>> listenersDict = new HashMap<Class<? extends Event>, Collection<Listener<? extends Event>>>();

public void registerListener(Listener<? extends Event> listener) {
Class<? extends Event> eventType = listener.getEventType();
Collection<Listener<? extends Event>> listeners = listenersDict.get(eventType);

if(listeners == null) {
listeners = new ArrayList<Listener<? extends Event>>();
listenersDict.put(eventType, listeners);
}
listeners.add(listener);
}

public void dispatch(Event event) {
Class<? extends Event> eventType = event.getEventType();
Collection<Listener<? extends Event>> listeners = listenersDict.get(eventType);

if(listeners != null) {
for(Listener<? extends Event> listener : listeners) {
if (listener.getEventType() == eventType) {
listener.onEvent(event);
}
}
}
}
}

监听器界面略有变化

public interface Listener<T extends Event> {
Class<T> getEventType();

void onEvent(Event event);
}

事件类没有变化:

public abstract class Event {
public final Class<? extends Event> getEventType() {
return this.getClass();
}
}

编辑:

作为对@jonathan.cone 的回应,我想指出这个解决方案确实会丢失实现 Listener 接口(interface)的类中的信息,这可能会破坏交易。

关于java - 实现事件驱动架构的类型更安全的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16577406/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com