我的问题很简单,可以说我有一个具有Number
值对象的Car
实体,并且具有Number
值对象的Truck
实体,
这是否意味着我在我的应用中有一个值对象,名为Number
的两个实体作为共享值对象?
,或者这取决于使每个实体有效的Number
?
根据定义的值对象是不可变的,应该可以安全地共享。它没有身份。我可以推荐埃里克·埃文斯(Eric Evans)的书籍域驱动设计(第5章详细说明了概念)。另外,请参阅Martin Fowler的文章
"这样做意味着我在应用程序中有一个值对象,名称为 两个实体作为共享价值对象?"
Number
可以是共享概念,如果它们都从根本上代表与无处不在的语言相同的东西。如果他们不这样做,则需要进行区分,例如CarNumber
和TruckNumber
(例如,两者都需要其他格式)。
一个说明,单独的上下文如果定义良好的情况通常足以避免术语过载,因此您很少会在有限的上下文(BC)中得到诸如UserAccount
和BankAccount
之类的东西,如果您这样做,那么您的BC边界是很可能是错误的。
但是,我相信Number
有些不同。因为这是一个众所周知的数学概念,很可能会在您的域中使用某些数学数字,所以我建议更具描述性来避免混乱,也许VehiculeNumber
?
首先,值对象 - 像大多数DDD工具一样 - 应该建模以解决域的无处不在语言的某些部分。
何时创建一个值对象?在书Implementing Domain Driven Design
中,沃恩·弗农(Vaughn Vernon)给出了一个值对象的这些特征
- 它可以测量,量化或描述域中的事物。
- 它可以保持不变。
- 它通过将相关属性作为整体单元组成。
- 这是完全当测量或描述更改时可更换。
- 可以是与其他使用价值平等相比。
- 它提供了无副作用行为的合作者
第一个公告意味着VO应该测量,量化或描述域中的事物。
接下来,它应该是不变的,并且不应具有状态变化的方法。这也适用于VO中的任何对象,如果VO使用它们,它们也必须更改。
继续前进,施工后必须完成vo。这意味着其所需的所有属性和属性必须处于有效状态。示例:价格VO必须在构造函数中同时设置具有正确值的currency
和amount
属性。
可复制性。这意味着可以用同一类型的另一种VO代替VO。如果您的VO可以将currency
设置为日元而不是美元,那么这可能会成为一个问题,因为您想更改(替换)price
的amount
,这可能会成为一个问题。
示例:一个实体接受具有currency
美元的CC_21和100,000的amount
。如果我们可以使用日元的currency
和200,000的amount
构建相同类型的新VO,那么此VO可能无法替代。当然,这将取决于您的域,但是如果实体的目的只是仅替换VO的货币价值,那么最好拥有单独的DollarVO
和YenVO
,以避免创建具有阻抗不匹配的属性的VO。<<<<<<<<<<<<
比较:VO应该与相同类型的其他VO实例相提并论。如果可以使用currency
属性构建VO,但在其他情况下却没有,则可能会违反可比性。IE。您应该能够使用两个相同的vo的实例,并比较其属性检查这些属性的不同值。如果缺少属性,则该比较因错误的原因而失败。
最后一个原理是不可分割的。如果您要提供VO的方法,请确保它们不会更改。