Search code examples
oopdomain-driven-designabstractionvalue-objects

Abstract properties as own value objects


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"


Solution

  • 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.