OOA&D / Java / 软件架构 - 建议构建事件处理代码以避免复杂的数据流

OOA&D / Java / Software Architecture - advise on structuring event handling code to avoid a complicated data flow

我在 Spring 中使用消息代理实现了 producer/consumer 范例,我的生产者使用 WebSocket 提取数据并将其发布到队列中。

生产者因此类似于: AcmeProducer.java handler/AcmeWebSocketHandler.java

处理程序一直很麻烦。

首先,处理程序有两个事件: 打开() onMessage()

onOpen 必须向网络套接字发送消息以订阅特定频道 onMessage 从WebSocket接收消息并加入队列

onMessage 有一些来自 AcmeProducer.java 的依赖,比如它需要知道要订阅的货币对,它需要消息代理服务,以及一个 ObjectMapper(json 反序列化器)和一个基准服务.

当消息从队列中被消费时,它们被转换为 OrderBook.java 的格式。每个生产者都有自己的 OrderBook 格式,因此也有自己的 AcmeOrderBook.java。

我觉得流程很难跟上,即使我已经将 classes 用于同一个包中的一个制作人。每次我想在生产者中修复某些东西时,我都必须在 classes 之间切换并搜索它在哪里。

是否有一些技术可以将复杂的数据流简化为易于理解的内容?

如您所知,像 AcmeHandler.java 这样的事件处理程序持有从系统其他地方(从 websocket 实现)调用的回调,因此它们可能很难组织。事件的数据流也更加复杂,因为当处理程序位于单独的文件中时,它们不能使用主文件中定义的变量。

如果此代码不使用事件驱动范例,则数据流将很容易遵循。

最后,在将 Web 套接字与 onOpen 和 onMessage 结合使用时,是否有构建代码的最佳实践? Producer/Consumer 是我能想到的最好的,但我不想将 classes 的 Acme 散布在不同的包中。例如,AcmeOrderbook 应该在消费者 class 中,但由于它依赖于 AcmeProducer.java 和 AcmeHandler.java,因此它们经常被同时编辑,因此我将它们放在一起。

由于每个 WebSocket 处理程序中的依赖项都是相同的(只是这些相同接口的不同实现)我认为应该只注入一件事,那就是一些上下文变量。这是最佳做法吗?

我已经使用 Message Dispatcher 和 Message Handlers 解决了这个问题。

调度程序仅检查消息是否为数据消息(快照或更新)并将控制权传递给消息处理程序 class,消息处理程序本身检查消息的类型(快照或更新)并处理正确输入。如果消息不是数据消息而是其他消息,调度程序将根据它是什么(某个事件)来发送消息。

我还使用匿名函数添加了回调,它们现在更短了,回调终于透明了。

例如,在匿名回调函数中只有这样:

messageDispatcher.dispatchMessage(context);

这里的另一个关键方法是使用上下文。MessageDispatcher 是一个单独的 class(自动装配)。

我已经将订单簿分离到每个生产者的目录中。

嗯,凡事都需要知识,才能优雅地解决这个问题。

解决此问题的最后一个模式:Java EE 对其端点和控制函数(如 onOpen、onMessage 等)使用注解。这也是一种不错的方法,因为有了它回调变得不可见并且 onOpen / onMessage由容器自动调用(使用注解)。