【问题标题】:Creating a simple event driven architecture创建一个简单的事件驱动架构
【发布时间】:2012-11-09 02:25:53
【问题描述】:

目前有一个项目有点麻烦。我正在实现一个游戏,我希望它是事件驱动的。

到目前为止,我有一个 EventHandler 类,它有一个重载方法,具体取决于生成的事件类型(PlayerMove、Contact、Attack 等)

我将让游戏驱动程序或类生成事件。我的问题是如何有效地处理事件而不将事件生成类与事件处理程序紧密耦合并且使 EDA 的使用变得多余?

我想设计自己的简单处理程序,而不是为此使用内置的 Java 处理程序

【问题讨论】:

  • 您的应用程序是多线程的还是您想使用同一个线程来生成/处理事件?
  • 好吧,做和 AWT 一样的事情:它使用事件处理程序的接口(在 AWT 中称为侦听器)。
  • 谢谢大家,它是单线程的。我正在寻找一个很好的简化代码,并解释如何实现 AWT 的功能,你有这样的链接吗?
  • 这主要是我在这里遇到问题的概念。我是否应该有一个静态事件处理程序,每个事件都将使用它的事件来调用它 - 例如,如果我有一个调用 EventHandler.HandleEvent(Attack) 的攻击()方法,那么在敌人中。我会有一个单独的类来定义攻击事件 - EventHandler.HandleEvent(new AttackEvent(data, target))
  • 这是一个更高级别的架构示例:medium.com/@wrong.about/…,这是一个更低级别的示例:medium.com/@wrong.about/…

标签: java events architecture event-driven


【解决方案1】:

如果您想拥有一个带有重载方法的 EventHandler 类并且您的事件类型没有任何子类,那么这个使用反射的简单代码应该可以工作:

public class EventHandler {
    public void handle (final PlayerMove move) {
       //... handle
    }

    public void handle (final Contact contact) {
       //... handle
    }

    public void handle (final Attack attack) {
       //... handle
    }
}

public void sendEvent (final EventHandler handler, final Object event) {
    final Method method = EventHandler.class.getDeclaredMethod ("handle", new Class[] {event.getClass ()});
    method.invoke (handler, event);
}

但是,如果您想为不同的事件设置单独的EventHandlers,以下会更好。

public interface EventHandler<T extends Event> {
    void handle (T event);
}

public class PlayerMoveEventHandler implements EventHandler<PlayerMove> {
    @Override
    public void handle (final PlayerMove event) {
        //... handle
    }
}

public class EventRouter {
    private final Map<Class, EventHandler> eventHandlerMap = new HashMap<Class, EventHandler> ();

    public void sendEvent (final Event event) {
        eventHandlerMap.get (event.getClass ()).handle (event);
    }

    public void registerHandler (final Class eventClass, final EventHandler handler) {
        eventHandlerMap.put (eventClass, handler);
    }
}

【讨论】:

  • 第二个例子不起作用。您不能将Event 传递给期望PlayerMove 的方法。如果处理程序需要子类型,您仍然需要使用反射来使用路由器将不同的类型传递给不同的处理程序。此外,ClassEventHandler 不应用作 EventRouter 中的原始类型。