Bob*_*r02 5 java events event-driven-design
我正在尝试开发一个基于处理某些事件和生成数据的系统。每个事件将包含(可能)几个不同的字段,每个侦听器将处理其中的一些。我有以下两种方法
在事件生成类中,我将注册多个事件侦听器,每个侦听器侦听事件特定字段的一个特定值,例如:
public class MicroListener implements Listener {
public void processEvent(Event e){
if(e.getName().equals(registeredName)) { ... }
}
Run Code Online (Sandbox Code Playgroud)这很诱人,因为处理是在对象本身内完成的,并且没有集中处理事件,而是允许每个对象处理信息。缺点(可能是致命的)是每个事件(几十万个)都必须广播给所有听众,而实际上只有一小部分会对其进行处理。从长远来看,它可能会产生巨大的性能冲击......
一个集中式侦听器,它将侦听所有事件并对其采取行动,并将处理委托给相应的事件处理器,例如:
public class CentralListener implements Listener {
Map<String, Processor> processorsByName;
public void processEvent(Event e){
processorsByName.get(e.getName()).process(e);
}
}
Run Code Online (Sandbox Code Playgroud)这会更快,但它需要单独的映射或处理器集合用于事件的任何其他部分,例如检查事件 ID 的处理器等。方法 1 中不是这种情况。因为我们将简单地生成另一组侦听器并注册它们与事件生成类。
大家觉得这些怎么样?它们是否有意义,还是您宁愿建议完全不同?
这是一个常见的设计决策,我认为没有一个适用于所有(甚至大多数)情况的通用答案。我可以列出这两种方法的各种权衡,但它们可能是显而易见的。在高层次上,在考虑可能的性能影响之前,我会倾向于最适合概念模型的设计(并且不会创建混乱的无关类)。
如果性能是最受关注的,那么使用大型 switch/case 块在整数事件 id 上切换的集中式控制器可能是最快的。...而且随着时间的推移也是最不灵活/可维护的。
您可能想查看Guava 项目的 EventBus。它使用注释来注册事件侦听器,并为此类事件广播/订阅提供非常干净的 API。事件订阅者根据他们在方法签名中声明的事件类型收到通知。它非常光滑并且节省了大量的样板文件。我不知道它能扩展到数千种事件类型,但与一些类似的库不同,事件总线不是全局的。您可以在有意义的情况下创建不同的事件总线实例来分隔事件处理。