我很困惑如何在域驱动设计中更新实体

I'm confused how to update Entity in Domain Driven Design

我正在学习 DDD,但遇到了一些麻烦。 我已经创建了具有值对象和一些用于操纵模型属性的函数的丰富域模型。 目前我在内存数据库中使用,我的域模型保持原样。 一切都很好。 但现在我想将域模型与数据库模型分开。

创建场景(比如说“音乐会”):

  1. 用户发送命令。
  2. 应用程序服务获取领域模型
  3. 然后应用程序服务调用存储库来持久化该模型
  4. 存储库(基础设施层)将该域模型转换为他的数据库模型并写入数据库

场景二(我要更新“演唱会”)

  1. 用户发送命令更新音乐会
  2. 应用程序服务调用存储库以获取要更新的“音乐会”(第一个问题是什么存储库应该 return 这里,它是否需要 return 域模型或其他东西)
  3. 现在(如果我有域模型)我可以调用方法 concert.sellTickets(3);
  4. 然后应用服务调用存储库来更新该音乐会

我的想法好吗?

存储库是否需要将 DB 模型重构为域模型并 return 重构为调用者?

我希望你明白我在问什么。

以上场景和一些示例代码:

创建音乐会(应用层)

// application service
var concert = Concert.Create(); // creating rich domain model or concert
_repository.Add(concert);

更新演唱会(卖票)-应用层

var concert = _repository.Get(//by id); // this is rich domain model
concert.SellTickets(//some number); // calling "smart" method 
_repository.Update(concert); // persisting to DB with new value

存储库端(写入)(基础设施层)

var concert = Adapter.Map(domain_model); // converting rich domain model to plain class for pesisting
_db.Add(concert);
_db.SaveChanges();

存储库端(阅读)-基础设施层

var concert = _db.Find(); // read concert from db
var rich_domain_model = Adapter.Map(concert) // convert it to rich domain model
return rich_domain_model;

我知道 ORM 使用他们的映射器, 但假设我现在正在内存数据库中使用。所以我需要做一些转换。

您介绍的这两个用例在 DDD 世界的上下文中是非常标准的。此外,它们反映了领域模型(领域层)和数据库模型(基础设施层)之间的有效分离。

  1. Application service gets domain model

“得到”是什么意思?用户接收到的命令对象是平面对象,不包含任何值对象;它不是(也不应该是)领域模型。可以将命令到域的转换委托给应用程序服务,但是有些人更愿意在 API 层内应用此类转换(这是个人喜好问题)。

User send command to update concert

“更新”一场音乐会的命令可能不止一个(例如,分配音乐家、订货大厅、卖票)。这就是为什么我们在 DDD 的上下文中定义单个更新操作时应该小心:发送具有许多彼此不一定相关的属性的命令是贫血模型的症状。

first question what repository should return here, does it need to return domain model or something else

存储库应将数据库对象转换为域实体,return 后者。在 DDD 中,所有层都“知道”域。

最后一点:

富域不仅仅是具有值对象和操作属性的方法的实体;丰富性应该通过“智能”方法来表达,即执行适当验证以防止实体进入不一致状态的方法。如果您想将域模型 按原样 投射到数据库中,智能实体没有意义,因为 运行 简单验证就足够了。但是,如果您的应用程序不是纯粹的 CRUD,提供丰富的流程和结构化的尽可能多的用户命令来改变业务实体,这就是 DDD 的亮点。