从聚合根或域服务调用持久性和服务?

问题描述 投票:0回答:1

我是领域驱动设计的新手,我正在努力解决在哪里调用对持久性、锁定和/或内部和外部服务的调用。在聚合根中?在周围的应用程序或域服务中?或者别的地方?为什么?

举个例子,让我们考虑一个购物车。它应该支持:

  1. 添加送货地址。执行此操作时,必须提供送货地址并根据公共在线地址验证服务进行验证。实际的 http 调用可以放在适配器中。但是适配器是在哪里调用的呢?
  • 来自购物车聚合根。优点:聚合根中的业务逻辑可以以不同的方式处理各种验证结果(例如请求用户提供丢失的信息)。缺点:可能需要几秒钟的时间,聚合根可以调用这样的外部服务吗?
  • 通过包含地址的 ValueObject。优点:ValueObject 在被聚合根接收时已经被验证。缺点:ValueObject 必须调用外部 http 服务,这对于值对象来说似乎相当繁琐。
  • 来自周围的应用程序/域服务?
  • 其他地方?
  1. 将产品添加到购物车。添加产品时,应在库存服务中检查该产品是否有库存。库存服务是同一应用程序中的应用程序/域服务。聚合根可以调用库存服务作为其“addProduct”方法的一部分吗?或者这应该首先由周围的域服务来完成?
  2. 持续状态。添加产品或结帐时,保留内部状态非常重要。持久性可以通过围绕数据库或某种其他类型的存储的适配器来提供。但是持久化(和加载数据)的行为是在哪里触发的呢?
  • 来自购物车聚合根?聚合根是否应该负责调用注入的持久性适配器?优点:聚合根可以控制何时保留数据的哪一部分(例如整个状态,或者只是一个新添加的产品)。缺点:聚合根承担多重职责(业务逻辑+持久性)。
  • 来自周围的应用程序或域服务?优点:保持聚合根清洁。缺点:从需要持久保存确切数据的聚合根进行通信更加复杂。
  1. 同步/锁定:有些操作需要多个动作。就像添加产品就是检查库存服务,将其添加到内部列表,更新订单总金额,然后持久化。当两次并行调用 add-product 导致内部管理或存储损坏时,这种情况是不好的,这种情况在未应用锁定时可能会发生。那么,应该在哪里进行锁定呢?
  • 来自购物车聚合根本身?优点:它控制何时加锁,何时使用读锁,何时使用写锁。缺点:这是另一种责任。聚合根不应该关注域逻辑而不是锁定等技术细节吗?
  • 来自周围的应用程序/域服务?优点:骨料根保持清洁。缺点:所有调用聚合根的代码都必须经过应用程序/域服务,并且应用程序/域服务必须了解聚合根的工作原理,以确定需要哪种类型的锁(读/写)。

在我们公司,我们对DDD都很陌生,我们有很多不同的意见。我们拥有像 Darlean 这样的(虚拟)参与者框架的经验,其中参与者类似于聚合根并且完全独立,因此它们提供自己的锁定,在需要时调用持久性,调用其他服务等等。 另一方面,我们使用一种方法,使聚合根尽可能最小,包含很少的业务逻辑,并且根本不调用外部或域服务。所有这些都是在围绕聚合根的应用程序服务中执行的。

您的意见/专业知识/建议是什么?外部服务调用/域服务调用/持久化调用/锁定调用放在哪里?在聚合根中?在周围的应用程序或域服务中?或者别的地方?为什么?

domain-driven-design ddd-repositories ddd-service
1个回答
0
投票

聚合根 此处不应提供外部服务调用或持久调用等技术细节。聚合根要保证业务逻辑的重点,管理核心业务流程。

我的建议是组织周围应用程序或领域服务中的技术细节,同时将核心业务逻辑保留在总根源上。这确保了代码保持干净并且职责明确分离

© www.soinside.com 2019 - 2024. All rights reserved.