抽象属性作为自己的值对象

Abstract properties as own value objects

给定以下示例:

class Person {
  Integer age
  String lastName
  String firstName 
}

属性 age 应受限于特定的验证规则:
- 高于 0

lastNamefirstName 相同:
- 这些字符串不应包含特殊字符(例如数字、下划线...)
- 长度应 > 0


为了抽象此验证策略,我是否应该创建值对象,例如 agename 以封装验证:

class Age {
  Integer value
}

class Name {
  String value
}

class Person {
  Name lastName
  Name firstName
  Age age
}

事实上,我也可以保持代码干燥并重新使用我的值对象,但它看起来像一个 "over-abstraction"

边栏:falsehoods programmers believe about names.

should I create value objects such as age and name in order to encapsulate the validation

这是一种权衡:值类型的创建允许您限制程序中需要验证的位置的数量。

使用强类型检查器,使用特定类型允许编译器保护程序员免受 class 错误。

此外,值类型的创建为您提供了与状态相关的方法的天然归宿。

它也将 Age 的消费者与内存表示隔离开来;例如,如果您稍后决定要更改年龄的 units,或者该年龄应该跟踪 age=0 的特定时间,那么您可以在一个地方,而不是到处。这是来自 Parnas -- Age 作为决定在内存中使用整数表示的边界。

当年龄不仅仅是一个领域不可知类型时,问题 "where are we using age in our code" 就更容易回答了。

相反 - 它增加了引入值类型的复杂性。

在许多情况下,定义域特定类型的好处大于成本。