DDD值对象与实体界定疑问及库存调整行项归类咨询
关于DDD中值对象与实体的疑问解答
场景结论
在你描述的库存调整单场景中,adjustmentLineItem应当作为库存调整聚合根内的值对象来设计。
疑问1:值对象的“无标识”是指无单独ID还是无复合标识?
值对象所说的“没有标识”,核心是指它不需要独立于自身属性之外的身份标识——不管是单独的ID字段,还是像AdjustmentID+ItemID这样的复合标识,都不属于值对象的领域模型范畴。
值对象的“身份”完全由它的所有属性值共同定义:只要两个行项的ItemID和Quantity完全相同,它们就是同一个值对象。你提到的AdjustmentID+ItemID只是存储或查询时的定位键,属于技术实现细节,不是领域模型中值对象的身份标识。
另外,值对象的设计原则是不可变:如果需要修改行项的数量,本质是用一个新的adjustmentLineItem值对象替换原有对象,而非修改原有对象的属性——这也进一步说明它不需要专属标识来追踪自身变化。
疑问2:值对象中包含父实体的标识(如adjustmentID)是否可行?
技术上可行,但从领域模型设计的角度完全没必要。
值对象是依附于聚合根(库存调整单)存在的,它的生命周期完全由聚合根管理。在领域模型层面,聚合根本身就知晓自己包含哪些值对象;当需要持久化时,存储层可以将聚合根ID与值对象的属性关联存储,这属于存储实现细节,不需要体现在领域模型的值对象中。
疑问3:值对象不应有标识的根本原因是什么?
值对象的核心职责是描述事物的属性特征,而非代表一个具有独立生命周期的个体。
- 实体的标识用于追踪个体的延续性:哪怕实体的所有属性都发生变化,只要标识不变,它仍是同一个实体。
- 值对象则没有这种“身份延续性”:属性值的变化意味着这是一个全新的值对象,而非原有对象的更新。
如果给值对象添加标识,会混淆它与实体的边界,导致你开始关注“值对象本身的变化”,而非它所代表的属性值,这违背了值对象简化领域模型、聚焦属性描述的设计初衷,还会不必要地增加模型复杂度。
内容的提问来源于stack exchange,提问作者Zeeshan Shamsuddeen
相关产品推荐
相关产品推荐

