聚合根的行为是否应该依赖于其他聚合根的属性?

时间:2013-12-28 12:20:44

标签: oop architecture domain-driven-design aggregation

我正在读一本关于DDD的书,我看到一个涉及汽车,发动机,车轮和轮胎的示例域名。

enter image description here

以上是本书中的模型。客户也是聚合根 拥有该模型,可能存在引擎可具有高度,宽度和长度属性的情况 当你需要在小型车上安装大型发动机时会发生什么?引擎无法适应。
如果汽车检查发动机属性并允许它或不成为汽车的一部分,这是一个问题吗? 引擎具有全局标识(就像您知道每个引擎都有一个序列号/制造商号)。也许引擎需要由制造商跟踪。

所以我再问一遍,如果汽车正在使用发动机的属性将其装入内部(允许它或不成为它的一部分),这是一个问题吗?

2 个答案:

答案 0 :(得分:2)

  

如果汽车检查发动机属性并允许它是否成为汽车的一部分,这是一个问题吗?

没有

话虽如此,您的验证可能非常复杂,无法引入域名服务。由于涉及两个聚合,您可以这样做:

car.Fit(engine)

或者这个:

engine.Fit(car)

但是,您可能想要检查汽车模型:)

由于规则会更高级并涉及一些数据,您可能想要引入域服务并可能在对象上使用双重调度:

所以而不是car.Fit(engine)你可以拥有这个:

car.Fit(engine, IModelServiceImplementation)

Fit方法调用中:

if (!IModelServiceImplementation.CanFit(car, engine)) { throw new Exception(); }

该服务可能会加载正确的模型,而是检查引擎。根据域名,甚至可能有修改级别和其他规则来处理。

由于Car实例不包含实际的Engine实例,而只包含EngineId或可能包含某个值对象,因此不会将引擎真正分配给汽车。您仍然可以将引擎实例传递给汽车并让它创建关联,但它认为合适。

'Enrico S.'提出的解决方案可能与对聚合根进行更改的情况更为相关,其中可能没有所有聚合根可用,或者甚至聚合根存在于单独的有界上下文中。即使CarEngine位于不同的BCs中,也可能会以某种方式查询有效性。有些事情对于最终的一致性是好的,但其他事情可能不是。

像往常一样,有很多事情要考虑:)

答案 1 :(得分:1)

来自DDD书,p128:

  

任何跨越AGGREGATES的规则都不会在任何时候都是最新的。通过事件处理,批处理或其他更新机制,可以在特定时间内解决其他依赖关系。

因此,它实际上取决于Car aggregate的设计:如果它需要与Engine强烈一致,那么Engine应该是Car聚合的一部分。 另一方面,如果它只需要“最终一致性”,您可以将该验证逻辑放在域事件中。

见此Udi Dahan的post