首先,值对象 - 就像大多数 ddd 实现一样 - 应该被建模以解决您领域中普遍存在的语言的某些部分。
何时创建值对象?在Implementing Domain Driven Design 一书中,Vaughn Vernon 给出了值对象的这些特征
- 它测量、量化或描述领域中的事物。
- 它
可以保持不变。
- 它通过以下方式对概念整体进行建模
将相关属性组成一个整体单元。
- 完全是
当测量或描述发生变化时可更换。
- 可以
与其他使用价值平等的人相比。
- 它提供其
无副作用行为的合作者
第一个公告意味着 VO 应该衡量、量化或描述领域中的事物。
接下来,它应该是不可变的,并且不应该有状态改变方法。这也适用于 VO 内的任何对象,如果 VO 使用它们,它们也必须永远无法更改。
继续前进,VO 必须在构建后完成。这意味着它需要的所有属性和属性都必须处于有效状态。示例:价格 VO 必须在构造函数中将 currency 和 amount 属性设置为正确的值。
可复制性。这意味着一个 VO 可以替换为另一个相同类型的 VO。如果您的 VO 可以将 currency 设置为日元而不是美元,那么这可能会在以后尝试替换 VO 时成为问题,因为您想将 amount 更改(替换)为 price。
示例:实体接受 VO Price,其中 currency 为美元,amount 为 100,000。如果我们可以用日元的currency 和 200,000 的amount 构造一个相同类型的新 VO,那么这个 VO 可能是不可替代的。这当然取决于您的领域,但如果实体的意图只是简单地替换 VO 的货币价值,那么最好有单独的 DollarVO 和 YenVO 以避免创建阻抗不匹配的 VO属性。
比较:VO 应该与其他同类型的 VO 实例具有可比性。如果可以使用 currency 属性构建 VO,但在其他情况下则不能,那么这可能会违反可比性。 IE。您应该能够获取相同 VO 的两个实例并比较它们的属性,仅检查这些属性的不同值。如果缺少属性,则比较因错误原因而失败。
最后一个原则是不可变性。如果您要提供 VO 的方法,请确保它们不会改变任何内容。