给定以下示例:
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
}
事实上,我也可以保持代码干燥并重用我的值对象,但这似乎是一个"过度抽象"的
边栏:程序员相信名字是假的。
我是否应该创建年龄和名称等值对象来封装验证
这是一种权衡:创建值类型可以限制程序中需要验证的位置数量。
使用强类型检查器,使用特定类型可以使编译器保护程序员免受一类错误的影响。
此外,值类型的创建为与状态相关的方法提供了一个自然的归宿。
它还将Age的消费者与记忆中的表现隔离开来;例如,如果您后来决定要更改年龄的单位,或者年龄应该跟踪年龄=0的特定时间,那么您可以在一个地方而不是在任何地方进行更改。这正是Parnas-Age
作为在内存中使用整数表示的决定的边界。
当年龄不仅仅是一个领域不可知的类型时,"我们在代码中使用年龄的地方"这个问题就更容易回答了。
与此相反,它增加了引入值类型的复杂性。
在许多情况下,定义域特定类型的好处大于成本。