在DDD聚合根目录中,应放置检查现有聚合的逻辑

时间:2019-02-08 10:00:43

标签: domain-driven-design aggregateroot domainservices

假设我有一个Order聚合根,并且当我收到创建Order的命令时,应在某些条件下检查其他订单,并在满足这些条件的情况下拒绝创建。检查此条件绝对是业务逻辑,但是在不满足条件的情况下,我不应该首先创建订单。 那么如何实施符合DDD原则的检查呢? 它是域名服务,应用程序服务的一部分吗?

编辑: Order中有TableId属性。 例如,我需要检查表是否已经被使用,如果是,则拒绝订单创建。该表服务可能驻留在另一个AppDomain中,并且可能需要网络调用。

我正在使用事件源,CQRS,命令处理程序。抱歉,我无法发布代码。

1 个答案:

答案 0 :(得分:1)

  

那么如何实施符合DDD原则的检查呢?

“取决于”。

如果您不需要需要所有内容完全一致,则可以为聚合提供其他数据的缓存副本以计算其逻辑。人们为此使用了不同的模式。使用域服务为您获取数据是另一回事,将控制权返回给应用程序以为您获取数据是另一回事...

----> create order
<---- here is a list of other information I need
----> the other information
<---- here's the order

需要带给业务专家的东西-如果其他数据是一秒钟旧的,那么计算是否足够准确?

另一方面,如果您需要所有内容都完全一致,那么您需要能够锁定其他信息,以便在进行计算时没有人可以更改这些详细信息。

该锁定可以是悲观的(锁定数据,然后进行计算),也可以是乐观的(获取数据的副本,执行计算,然后锁定数据并确保未更改)。

这是“坏”消息:在域驱动的设计模式中定义锁的机制是集合。聚合是coarse grained lock模式的表达;当您需要锁定一堆数据时,企业会告诉您这些数据都应该属于 same 聚合的一部分。

有时候,当您发现业务规则根本不符合那些边界时,您会遇到一个漂亮的域模型,其中的聚合表达了许多显而易见的域概念,组织数据边界以使规则生效。

开始设计模型时,通常会将聚合想象为流程,然后将那些需要能够锁定彼此数据的流程分组在一起,通常是个好主意。

  

例如,我需要检查表是否已被使用,如果是,则拒绝订单创建。该表服务可能驻留在另一个AppDomain中,并且可能需要网络调用。

当权威数据位于其他位置时,则无需考虑锁定。从尽力而为,异常报告和缓解冲突方面进行思考。