具有写模型约束的聚合之间的引用



我知道这里有很多关于聚合引用的问题。但读了其中一些后,我仍然没有得到答案。

首先我将描述我的业务逻辑。

我有两个实体

Resource,表示计算单元的资源,包括cpu、gpu、内存、磁盘。Resource可供用户使用

class Resource {
CPU cpu;
GPU gpu;
Memory memory;
Disk disk;
int totalCount; // The number of resource if limited
boolean isAvailable; // Resource can be unavailable
List<UserId> whiteLists; // Resource can give a white list where only limited users can use
}

Plan是商品。它具有价格,并与Resource和时间绑定。

class Plan {
String resourceId;
Money price;
int hours;
}

现在我只是保存resourceIdPlan遵循DDD原则:Aggregates should reference other aggregates by Id。但是这里有一些业务逻辑使它变得相当困难:

  1. Plan也应该遵循Resource.whiteList,这意味着当Resource只被一些用户访问时,使用ResourcePlan也应该遵循whiteList
  2. 如果Resource不可用,则Plan不可用。具有相同Resource(但时间不同)的
  3. Plan应该遵循一些变体。例如,使用更多时间的Plan应该总是比使用更少时间的Plan昂贵。

这三个逻辑都意味着Plan应该总是访问Plan.Resource。我认为这不仅仅是CQRS读取模型的逻辑,它只显示计划和资源在一起。甚至在一些Plan创建工作流程中也是必要的。

所以现在我认为在Plan中使用Resource是非常必要的。但是如何解决与DDD原则的冲突,我只是不知道如何解释这种情况。我把它们当作两个单独的集合有错吗?但是PlanResource确实需要单独编辑。

更新有一些细节我没有描述好。

  1. Plan在很长的生命周期内不会超过100。
  2. PlanResource只能由管理员编辑。这里不存在并发性问题。Plan可以购买用户,但用户从不编辑它。
  3. Plan应该始终遵循Resource中的whiteList,如果一个用户购买了Plan,他/她甚至没有权利使用Resource,这是不可接受的。

该原则用于提示聚合的边界。
可以通过在创建计划之前查询"资源"来达到相同的效果。
查看不解决问题的验证规则,如何知道资源在给定时间内是否空闲?
您需要检查与该资源关联的所有计划以了解它。

现在有两种方法来解决这些不变量:
1。
有一个单独的聚合资源,其中有一个List<Plan>,它负责创建它们,并可以保证不变量的100%一致性。
2。
将它们分开,通过一些服务创建一个计划,该服务执行一些查询来检查资源和其他计划的状态,以确保不变性,然后创建新的聚合。

解决方案1很难扩展,与单个资源关联的Plan越多,您将需要更多的优化以获得良好的性能。
方案2允许不一致性,可能发生并发操作允许同时创建两个Plan,或者为同时从白名单中删除的用户创建一个Plan。

解决方案1,什么"性能好";意味着什么?一共有多少个计划?
解决方案2并发写发生的概率是多少?这个错误率可以接受吗?这些问题发生后能得到管理吗?

没有一般的正确答案,这取决于你的具体用例。

相关内容

  • 没有找到相关文章

最新更新