处理多级事件的最佳设计

OoD*_*lly 5 architecture events event-handling microservices

我有 4 个实体:

  • Mall包含多个子Shop对象
  • Shop包含多个子Basket对象
  • Basket包含多个Fruit子对象。
  • Fruit这是一个叶子子对象。

在此输入图像描述

updateMall(...)呼唤updateShop(...),呼唤updateBasket(...),呼唤updateFruit(...)

每个函数完成后updateXxx(...)都会发送一个。XxxUpdatedEvent

因此,如果updateMall(...)调用,将会发送很多事件:FruitUpdatedEvent, BasketUpdatedEvent, ShopUpdatedEvent, MallUpdatedEvent

这种事件粒度是理想的,因为一些事件监听器可能只关心例如BasketUpdatedEvent而不一定关心父数据事件。

这是 2 个生产者和 2 个侦听器的序列图:

在此输入图像描述

正如您所看到的,Listener2需要使所有数据与其自己的内部业务逻辑保持同步。因此,它需要倾听一切。它不能只听MallUpdatedEvent,因为有时只会FruitUpdatedEvent发出。

(在我的现实生活场景中,这Listener2是一个 ElasticSearch 索引,试图跟上更改的数据)。

正如您所看到的,这里的问题是嵌套同步的冗余。子对象同步方法的调用次数超出了一遍又一遍地执行相同作业所需的次数。

我很确定这个设计问题很常见,人们必须一遍又一遍地解决它,但不幸的是我的谷歌搜索努力没有得到回报。什么是一个好的设计模式来以高效、精细和优雅的方式解决这个问题?

我想到了一些去抖机制,但它并不是万无一失的。

Jul*_*ian 1

从您的问题来看,您似乎可以设计系统来维护以下不变量,并且您可能已经这样做了:

  1. updateFruit是你逻辑中唯一可以改变水果的地方。
  2. updateFruit 总是触发FruitUpdatedEvent.

对于其他实体类型也是如此。updateBasket可能会添加、删除或重新排序与篮子相关的水果,但对水果本身的更改将推迟到updateFruit

在这些不变量下costlyBasketSynchronize不需要调用. 毕竟,如果篮子中的任何水果与篮子本身一起被修改,那么就已经被触发并处理了。这一原则也适用于更高级别的嵌套。costlyFruitSynchronizeFruitUpdatedEvent

Backbone是 JavaScript 的客户端框架,自 2010 年以来一直成功遵循这一原则。它具有类似的层次结构,但只有两个级别。较小的实体称为Model,包含一个的较大实体称为Collection

Model有一个set方法来更新其属性。如果任何属性的值发生更改,模型就会触发change事件。

Collection还有一个set方法,更新其模型。这可能会添加、删除或重新排序与集合关联的模型。此外,它还会递归调用set每个模型的方法来更新其属性,这反过来可能会触发change事件。update集合本身最终会触发一个事件,无论其中的任何模型是否更改了属性。

对数据结构的两个级别都感兴趣的侦听器只需订阅changeupdate事件。侦听change器处理模型属性更改,同时update侦听器处理集合组成更改。这是一个非常干净的关注点分离,系统中没有冗余。