经过多次阅读和思考,我开始把头脑包裹在DDD之后,我对在聚合根下处理复杂层次结构的最佳实践感到困惑.我认为这是一个FAQ,但在阅读了无数的例子和讨论之后,没有人在谈论我所看到的问题.
如果我与DDD思想保持一致,那么聚合根下面的实体应该是不可变的.这是我的麻烦的关键,所以如果这不正确,那就是我失败的原因.
这是一个捏造的例子......希望它有足够的水来讨论.
考虑汽车保险政策(我不是保险,但这与我在保险公司打电话时听到的语言相符).
政策显然是一个实体.在政策中,假设我们有自动.出于此示例的目的,Auto仅存在于策略中(可能您可以将Auto转移到另一个策略,因此这也可能是聚合,这会更改策略...但是假设它比现在更简单) .由于没有策略,Auto不能存在,我认为它应该是实体而不是根.因此,在这种情况下,策略是聚合根.
现在,要创建一个策略,我们假设它必须至少有一个自动.这是我感到沮丧的地方.假设Auto相当复杂,包括许多字段,也许是一个儿童用于车库的位置(位置).如果我理解正确,"创建策略"构造函数/工厂必须将Auto作为输入或通过构建器限制,以便在没有此Auto的情况下创建.并且Auto的创建,因为它是一个实体,不能事先完成(因为它是不可变的?也许这只是一个不正确的解释).所以你不要说新的Auto然后setX,setY,add(Z).
如果Auto不仅仅是微不足道的,那么您最终必须构建一个庞大的构建器层次结构,以便尝试在策略的上下文中管理创建Auto.
稍后,在创建策略并且希望添加另一个Auto ...或更新现有Auto之后,还有一个问题.很明显,政策控制了这个...很好......但是Policy.addAuto()不会完全飞行,因为一个人不能只传入一个新的Auto(对!!).例子说像Policy.addAuto(VIN,make,model等),但都很简单,看起来很合理.但是如果这种工厂方法方法因参数太多而分崩离析(整个Auto接口,可以想象)我需要一个解决方案.
从我的思考中,我意识到对一个实体进行瞬态引用是可以的.所以,也许在瞬态环境中在聚合体之外创建一个实体是可以的,所以也许可以这样说:
auto = AutoFactory.createAuto(); auto.setX auto.setY
或者如果坚持不变性,AutoBuilder.new().setX().setY().build()
当你说Policy.addAuto(auto)时它会被整理出来
如果您添加事件,例如带有PolicyReports或RepairEstimates的事故......某些值对象,但大多数实体在策略之外都没有任何意义,这个保险示例会变得更有趣......至少对于我的简单示例.
政策的生命周期随着时间的推移逐渐增加,这似乎是我在真正开始挖掘之前必须绘制的基本图景......而且更多的是工厂概念或子实体如何构建/附加到我没有的聚合根看到了一个坚实的例子.
我想我很亲密.希望这是明确的,而不仅仅是重复的常见问题解答,它在各处都有答案.