0

Given the following example:

class Person {
  Integer age
  String lastName
  String firstName 
}

The property age should be constrained to specific validation rules:
- Higher than 0

Same for the lastName and firstName:
- These strings should not contain special characters (e.g. numbers, underscore, ...)
- Length should be > 0


In order to abstract this validation policy, should I create value objects such as age and name in order to encapsulate the validation:

class Age {
  Integer value
}

class Name {
  String value
}

class Person {
  Name lastName
  Name firstName
  Age age
}

Indeed I can also keep the code DRY and re-use my value objects but it seems like an "over-abstraction"

Simon Bruneaud
  • 2,263
  • 2
  • 12
  • 24

1 Answers1

2

Sidebar: falsehoods programmers believe about names.

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

It's a trade off: the creation of a value type allows you to limit the number of places that validation is required in your program.

With a strong type checker, using a specific type allows the compiler to protect the programmer from a class of errors.

Furthermore, the creation of value types gives you a natural home for methods related to the state.

It also insulates the consumers of Age from the in memory representation; for example, if you were to later decide that you wanted to change the units of age, or that age should track the specific time that was age=0, then you can make that change in one place, rather than everywhere. This is right from Parnas -- Age serves as a boundary around the decision to use an integer representation in memory.

The question "where are we using age in our code" is a lot easier to answer when age is not merely a domain agnostic type.

Against that - it adds does add some complexity to introduce value types.

In many cases, the benefits of defining domain specific types outweigh the costs.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91