我想模拟简单游戏的领域。
我们有一个可以购买不同建筑物的玩家,他还有一个股票,玩家可以拥有其他我将要添加的东西。但是现在我只专注于建筑物和库存。
我决定将它分为三个聚合根源Player,PlayerBuildingManagment,PlayerStock。我不确定它是否是正确的除法,因为Stock和PlayerBuildingManagment与Player非常相关,因此它不应该是聚合根。另一方面,我不想创建一个巨大的聚合。在我的情况下,并发性不会成为问题,因为所有库存,构建管理只会被一个玩家修改。
播放器
库存 1. AddToStock() 2. TakeFromStock()
PlayerBuildingManagment 1. AddBuilding()
现在我需要实施玩家购买建筑物的过程,所以我需要
我可以在一个服务函数中实现这个过程,但据我所知,我们不应该在一个事务中修改两个聚合的状态。你怎么看待这种沟通应该如何实现。 也许我应该在玩家聚合中实现股票和建筑管理。或者创建一些流程管理器来进行此通信。能不能给我一些线索。
答案 0 :(得分:0)
获取聚合之间的事务一致性,根据定义,它们是自己的一致性边界,至少可以说是有问题的。
让我们继续你的想法,即有玩家,PlayerStock - 就像银行一样,而PlayerBuildingManager - 就像承包商一样。
关于检查足够库存的问题以及玩家P为成本X建造建筑物Y的请求,我可能会向PlayerStock聚合发送一个带有这些参数的命令:
这个给PlayerStock的消息的来电者将提供一个“做什么”,它有效地代表了一个成功发送给别人的消息(你可能还有一个“怎么做”失败,但那是另一个物)。
在这种情况下,“要做什么”消息参数将编码一个命令,用于为玩家X构建建筑物Y,并将其发送到PlayerBuildingManager。
其余部分可以通过多个聚合的典型一致性来处理。
因此,某些控制器通过UI向PlayerStock发送消息,从玩家P中扣除一些金额X,并在成功时发送一些消息。成功时,它将执行成功消息,这是向PlayerBuildingManager发送消息以构建玩家P的建筑物Y.将有一个最终的一致性周期,其中已扣除库存但建筑物尚未实现。这是您在使用多个聚合时所采用的最终一致性。
将成功消息编码为参数的原因是,您可以更加松散地将PlayerStock与可以构建的事物的目录以及谁可以构建它们结合起来。作为参数的任意成功消息将提供高度的灵活性,而不必让PlayerStock知道太多。
(如果你不想处理它,你当然可以将它们全部放在同一个聚合中。)
如果你想进一步:
假设PlayerBuildingManager在从PlayerStock收到的命令中构建建筑物失败。好吧,它应该归还股票。但是为了保持松散耦合,PlayerStock可以在这种情况下发送信息,将X返回给PlayerStock for P.。
此外,您可能会考虑如果建筑物的构造不只是延迟而是实时(如现实世界中的情况)会发生什么。在这种情况下,玩家可能想要取消施工,可能会或可能不会这样做,并可能全额退款或部分退款...