在DDD聚合根中,检查现有聚合的逻辑应该放在哪里
In DDD aggregate root, where should be placed logic of checking existing aggregate
假设我有一个 Order
聚合根,当我收到创建 Order
的命令时,我应该在某些条件下检查其他命令,如果满足这些条件,则拒绝创建。检查这个条件肯定是业务逻辑,但我不应该在不满足条件的情况下首先创建订单。
那么如何实现这个符合DDD原则的检查呢?
它是域服务、应用程序服务的一部分吗?
编辑:
Order
中有 TableId 属性。
例如,我需要检查 table 是否已被占用,如果是,则拒绝创建订单。此 table 服务可能驻留在另一个 AppDomain 中,可能需要网络调用。
我正在使用事件源、CQRS、命令处理程序。抱歉,我无法 post 验证码。
So how to implement this check that complies with DDD principles?
"It depends".
如果您不需要一切都完全一致,那么您可以为聚合提供其他数据的缓存副本以计算其逻辑。人们为此使用不同的模式;使用域服务为您获取数据是一种,将控制权返回给应用程序以获取数据是另一种...
----> create order
<---- here is a list of other information I need
----> the other information
<---- here's the order
这件事要交给业务专家——如果其他数据是一秒前的数据,计算是否足够准确?
另一方面,如果您需要一切都完全一致,那么您需要能够锁定其他信息,以便在您进行计算时没有人可以更改这些细节。
这个锁可以是悲观的(锁定数据,然后进行计算),也可以是乐观的(获取数据的副本,执行计算,然后锁定数据并确保它没有改变)。
这里是 "bad" 消息:在域驱动设计模式中定义锁的机制是聚合。聚合是 coarse grained lock 模式的表达式;当你需要锁定一堆数据时,这就是业务告诉你数据应该都是 same 聚合的一部分。
当您发现业务规则根本不符合这些边界时,有时您会拥有一个漂亮的领域模型,其中包含表达一堆明显领域概念的聚合,并且您必须重新组织您的数据边界以使规则生效。
在开始模型设计时将聚合想象为 进程 并将需要能够锁定彼此数据的进程组合在一起通常是个好主意。
For example I need to check if table is already taken, and if it is, decline order creation. This table service may reside in another AppDomain, and network call maybe needed.
当权威数据存在于其他地方时,忘记锁定。考虑最大努力、异常报告和冲突缓解。
假设我有一个 Order
聚合根,当我收到创建 Order
的命令时,我应该在某些条件下检查其他命令,如果满足这些条件,则拒绝创建。检查这个条件肯定是业务逻辑,但我不应该在不满足条件的情况下首先创建订单。
那么如何实现这个符合DDD原则的检查呢?
它是域服务、应用程序服务的一部分吗?
编辑:
Order
中有 TableId 属性。
例如,我需要检查 table 是否已被占用,如果是,则拒绝创建订单。此 table 服务可能驻留在另一个 AppDomain 中,可能需要网络调用。
我正在使用事件源、CQRS、命令处理程序。抱歉,我无法 post 验证码。
So how to implement this check that complies with DDD principles?
"It depends".
如果您不需要一切都完全一致,那么您可以为聚合提供其他数据的缓存副本以计算其逻辑。人们为此使用不同的模式;使用域服务为您获取数据是一种,将控制权返回给应用程序以获取数据是另一种...
----> create order
<---- here is a list of other information I need
----> the other information
<---- here's the order
这件事要交给业务专家——如果其他数据是一秒前的数据,计算是否足够准确?
另一方面,如果您需要一切都完全一致,那么您需要能够锁定其他信息,以便在您进行计算时没有人可以更改这些细节。
这个锁可以是悲观的(锁定数据,然后进行计算),也可以是乐观的(获取数据的副本,执行计算,然后锁定数据并确保它没有改变)。
这里是 "bad" 消息:在域驱动设计模式中定义锁的机制是聚合。聚合是 coarse grained lock 模式的表达式;当你需要锁定一堆数据时,这就是业务告诉你数据应该都是 same 聚合的一部分。
当您发现业务规则根本不符合这些边界时,有时您会拥有一个漂亮的领域模型,其中包含表达一堆明显领域概念的聚合,并且您必须重新组织您的数据边界以使规则生效。
在开始模型设计时将聚合想象为 进程 并将需要能够锁定彼此数据的进程组合在一起通常是个好主意。
For example I need to check if table is already taken, and if it is, decline order creation. This table service may reside in another AppDomain, and network call maybe needed.
当权威数据存在于其他地方时,忘记锁定。考虑最大努力、异常报告和冲突缓解。