抽象属性作为自己的值对象
Abstract properties as own value objects
给定以下示例:
class Person {
Integer age
String lastName
String firstName
}
属性 age 应受限于特定的验证规则:
- 高于 0
lastName 和 firstName 相同:
- 这些字符串不应包含特殊字符(例如数字、下划线...)
- 长度应 > 0
为了抽象此验证策略,我是否应该创建值对象,例如 age 和 name 以封装验证:
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" 就更容易回答了。
相反 - 它增加了引入值类型的复杂性。
在许多情况下,定义域特定类型的好处大于成本。
给定以下示例:
class Person {
Integer age
String lastName
String firstName
}
属性 age 应受限于特定的验证规则:
- 高于 0
lastName 和 firstName 相同:
- 这些字符串不应包含特殊字符(例如数字、下划线...)
- 长度应 > 0
为了抽象此验证策略,我是否应该创建值对象,例如 age 和 name 以封装验证:
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" 就更容易回答了。
相反 - 它增加了引入值类型的复杂性。
在许多情况下,定义域特定类型的好处大于成本。