gpt4 book ai didi

client-server - DDD - 在不更新整个聚合根的情况下更新实体的小细节

转载 作者:行者123 更新时间:2023-12-04 14:17:19 27 4
gpt4 key购买 nike

假设我的 AggregateRootOrder-Model。有一个包含 OrderItems(实体)的集合。我只有一个 Repository 用于 AggregateRoot(订单),但没有用于 OrderItems。

当客户只想更新一个小的更改,例如一个 OrderItem 上的 Remarks 字段时,我该怎么办?

我目前的理解是客户端通过DTO 发送更新。然后中间件加载整个订单,然后更新单个细节,并将整个订单提交到存储库。

如果我理解正确的话,这是现实生活中的一个好习惯,还是您会以不同的方式处理它?这听起来对我来说性能不佳且维护不友好。

最佳答案

正如 DDD 中的所有内容一样,答案在于领域规则。一切都必须围绕规则而不是数据结构。

警告:下面的例子太简单了!

您必须更改一个订单项的Remarks 字段,所以请问您:Remarks 字段更改操作有哪些限制和不变性? OrderItem 是否具有为此所需的所有信息?如果是,那么在这种情况下 OrderItem 是您的聚合根。

是否某些备注不允许进入 OrderItem,因为它属于某种类型的订单,但其他订单类型允许此备注。那么 Order 就是你的聚合根。

这为您提供了有关如何处理它的线索,但是因为您的评论加载一个包含所有 OrderItems 的订单只是为了更改一个 OrderItem Remark 是绝对不高效的。

“I’m sorry that I coined the term ‘objects,’ because it gets many people to focus on the lesser idea. The big idea is ‘messaging’” ~ Alan Kay

还记得我说过 DDD 必须强调环绕规则而不是环绕数据结构吗?所以,不要考虑数据结构。围绕命令和事件(消息)和规则对所有事物进行建模。让你的持久性存储库为该命令带来适当的聚合根,使用 AR 来应用命令,返回一个域事件产生的变化,并使用该事件来持久化新的系统状态并通知其他服务有关变化。

来自 Aggregate root invariant enforcement with application quotas 的代码示例

class ApplicationService{
public void registerUser(RegisterUserCommand registerUserCommand){

var user = new UserEntity(registerUserCommand.userData); //avoid wrong entity state; ctor. fails if some data is incorrect

RegistrationAggregate agg = aggregatesRepository.Handle(registerUserCommand); //handle is overloaded for every command we need. Use registerUserCommand.tenantId to bring total_active_users and quota from persistence, create RegistrarionAggregate fed with TenantData

var userRegisteredEvent = agg.registerUser(user); //return domain changes expressed as a event

persistence.Handle(userRegisteredEvent); //handle is overloaded for every event we need; open transaction, persist userRegisteredEvent.fromTenant.total_active_users where tenantId, optimistic concurrency could fail if total_active_users has changed since we read it (rollback transaction), persist userRegisteredEvent.user in relationship with tenantId, commit transaction

eventBus.publish(userRegisteredEvent); //notify external sources for eventual consistency

}

这允许您从持久性中将 OrderItemRemarkManagerAggregate 带入内存,其中仅包含更改备注所需的信息(即 OrderItem ID、当前备注、OrderItem 状态、所属的 OrderType 等);只需使用它来应用操作并将更改应用到持久性。

稍后您可能会担心为多个操作重用聚合(当然总是在同一个限界上下文中)或者甚至根据需要进行重构。

关于client-server - DDD - 在不更新整个聚合根的情况下更新实体的小细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59035684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com