如何使用Akka对聚合关系建模

dsekswqp  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(162)

我很难处理参与者模型中的关系。让我用一个简单的例子。系统中有两种参与者类型:仓库和项目。项目总是分配给特定的仓库。AddStock命令允许增加分配给给定仓库位置的库存数量。只有仓库知道自己的位置,所以项目必须询问它的仓库,如果位置是有效的,以执行自己的业务逻辑。我想到了一些解决方案
1.命令AddStock包含对仓库碎片区域的ActorRef,该区域允许Item询问仓库有关位置的信息。
1.只允许仓库发出AddStock命令,允许预验证位置。不知道如何实现这一点,我考虑过私有命令或一些识别过程
我不喜欢这两个解决方案。它给简单的任务增加了很多不必要的复杂性。我认为这可能是OOP思想的问题,分布式参与者世界由它自己的规则管理。
在我的场景中,我将Item和Warehouse看作是独立的聚合体,它们都被实现为Persistent Actor(使用Cluster Sharding)。
只要你假设只有Warehouse可以调用Item::AddStock,那么一切都很容易。Warehouse只在调用之前验证位置。但是你可以直接调用Item,跳过所有验证。Item没有办法知道是否是正确的Warehouse进行了调用。这在纯OOP/DDD方法中很容易实现。Item知道Warehouse ID,变化的数量看起来像这样

item.addStock("L2", 100, warehouse)

知道仓库id的项目可以验证所提供的仓库是否是仓库。并且具有仓库的项目可以询问位置是否有效。我当前的项目处理程序实现:

case AddStock(region, location, quantity) => {
  region ? EntityEnvelope(warehouseId, HasLocation(location)) map (
    _ => VerifiedAddStock(quantity)
  ) pipeTo self

VerifiedAddStock是Item的私有对象,所以我可以确定谁是命令发布者(几乎是因为它不强制标识)。
因此问题是如何在Actor世界中建模这种关系?
有人可能会认为这是由于不正确的聚合/参与者边界导致的设计缺陷本身,但这只是一个示例。

lvmkulzt

lvmkulzt1#

项目是否包含仓库不关心的任何信息(如描述)?
如果答案是否定的,那么我就把Item当作关联仓库位置的子项(即反转关系的方向)。只要仓库从不为Item提供ActorRef,就可以确保只有它可以向Item参与者发送消息(Akka Typed让您做出这种静态保证)。
如果答案是肯定的,我建议在仓库库存的上下文中,Item由该上下文中所需的确切信息组成,例如,目录描述之类的内容由不同的上下文负责(很可能是不同的服务),以及目录描述上下文是否需要了解有关库存的某些信息(例如,是否有库存),那么它应该利用仓库库存发出的域事件。

相关问题