领域驱动设计; ValueObject 可以包含不变量或规范吗?

Domain Driven Design; Can ValueObject contains invariants or specifications?

我开始玩域驱动设计,对 ValueObjects 有疑问:

它们可以包含不变量或其他规范吗?

考虑一个不可变的 ValueObject :

ValueObject (

  prop integer: Int
  prop string: String

  // Value and copy constructor

  // Observers for integer and string

  // Equality methods on integer and string value

)

我可以添加一些不变量使得 整数 > 0 & < 42。或者它们必须是没有任何逻辑的简单传输?

我希望他们可以,但需要确认。

值对象 (VO) 封装了一个值及其其业务需求。这就是它的目的:对恰好是一个简单(并不总是单一)值的业务概念(及其约束)进行建模。

VO 不是数据传输对象 (DTO),正是因为它定义了一个业务概念,该概念仅在包含的有界上下文中有效,而 DTO 旨在跨越边界。

值对象应该处理它们封装的数据的不变量,或者至少尽可能多地处理它。我倾向于执行以下操作,这实际上类似于实体,除了不可变位:

  • 构造函数应确保它是在有效状态下创建的
  • VO的状态是封装的,所有的改变都是通过controlled methods/etc
  • 因为值对象是不可变的,所以方法会更改 return 一个新的值对象而不是更新现有状态

让值对象拥有自己的业务逻辑确实有助于清理使用这些值对象的实体中的代码。这可能成为大 aggregates\entities 的问题,因此寻找机会将此行为拉出到值对象中。

它还使单元测试许多边缘情况变得容易得多,因为您正在单独测试值对象。

您的实体可能需要在决定可以发生更改之前对多个值对象进行验证,但随后值对象将对更改本身负责。