【问题标题】:Java - event processing designJava——事件处理设计
【发布时间】:2012-11-03 12:05:35
【问题描述】:

我正在尝试开发一个基于处理某些事件和生成数据的系统。每个事件将包含(可能)几个不同的字段,每个侦听器将处理一些或它们。我想到了以下两种方法

  1. 在事件生成类中,我将注册多个事件监听器,每个监听事件特定字段的一个特定值,例如:

    public class MicroListener implements Listener {
    
    public void processEvent(Event e){
        if(e.getName().equals(registeredName)) { ... }
    }
    

这很诱人,因为处理是在对象本身内部完成的,并且没有集中处理事件,而是允许每个对象处理信息。缺点,可能是致命的,是每个事件(几十万个)都必须广播给所有听众,而实际上只有一小部分会做某事。从长远来看,它可能会产生巨大的性能冲击......

  1. 一个集中式侦听器,它将侦听所有事件并对其采取行动,并将处理委托给相应的事件处理器,例如:

     public class CentralListener implements Listener {
    
        Map<String, Processor> processorsByName;
    
        public void processEvent(Event e){
            processorsByName.get(e.getName()).process(e);
        }
    }
    

这会更快,但它需要单独的映射或处理器集合用于事件的任何其他部分,例如检查事件 ID 等的处理器。方法 1 中不是这种情况。因为我们将简单地生成另一组侦听器并将它们注册到事件生成类。

你们怎么看这些?它们是否有意义,还是您更愿意为完全不同的事物提供建议?

【问题讨论】:

    标签: java events event-driven-design


    【解决方案1】:

    这是一个常见的设计决策,我认为没有适用于所有(甚至大多数)情况的通用答案。我可以列出这两种方法的各种权衡,但它们可能是显而易见的。在我考虑可能的性能影响之前,我会优先考虑最适合概念模型的任何设计(并且不会产生一堆无关的类)。

    如果性能是最受关注的问题,那么在整数事件 ID 上使用大型 switch/case 块切换的集中式控制器可能是最快的。 ...并且随着时间的推移也是最不灵活/可维护的。

    您可能想查看Guava project's EventBus。它使用注解来注册事件监听器,并为这种类型的事件广播/订阅提供了一个非常干净的 api。根据他们在方法签名中声明的事件类型通知事件订阅者。它非常光滑并且节省了很多样板文件。我不知道它可以扩展到数千种事件类型,但与一些类似的库不同,事件总线不是全局的。您可以创建不同的事件总线实例以在有意义的情况下分隔事件处理。

    【讨论】:

      【解决方案2】:

      听起来您正处于一个相当大且(可能)复杂的事情的开始阶段。在使用您提到的两种更具命令式启发的方法之前,我可能会仔细研究基于事件的编程。这个想法与使用侦听器非常相似,只是异步实现,因此事件侦听器可以是它们自己的小线程,仅在被要求执行时才执行。

      我不知道它是否适用于此,但我们假设您有不同的事件类型需要传播到不同的侦听器。与其将观察者存储在一个巨大的堆中,不如为观察者可以注册的每种事件类型创建一个侦听器?如果您有一些生成事件的核心组件,它们可以将它们发送到侦听器,然后再将它们发送给观察者。

      在我看来,主要的好处是在得到照顾之前将责任委托给(子)听众。在一个可以真正帮助程序员并防止性能瓶颈的大型环境中。我相信这也称为reactor pattern

      如果您正在寻找灵感,请尝试查看akka framework。它专为高效的分布式事件编程而设计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-23
        • 2012-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多