In domain driven design (DDD) we talk a lot about entities; objects that have identity and lifetimes that typically outlive their values. e.g. An account lives longer than the email address, name, postal address etc. Value types might be mentioned in discussion but then quickly fade. This is a shame because they are the fundamental building blocks, after all they hold the application data. One reason for this lack of attention is that we have some pretty powerful substitutes already supported by our implementation languages - int, double, string. But is that really good enough?

Consider:

...
Email e = new Email("Graham", "Brooks", "[email protected]");

e.sendTo(...)
...

which uses the Email constructor:

class Email {

    public Email(String firstName, String secondName, String emailAddress) { ... }
    ...
}

Tests are the only thing that are going to stop things like:

...
Email e = new Email("[email protected]", "Graham", "Brooks");

e.sendTo(...)
...

making it into production but it does add to developer workload - because every time I need to call a method with the String, String, String parameters I need to check and double check. I want my language and tools to work for me not against me.

If we take moment and create some pretty simple types then (UML diagrams using PlantUML):

value types 1
class Email {

    public Email(Name userName, EmailAddress emailAddress) { ... }
    ...
}

And the calling code:

...
Email e = new Email(new Name("Graham", "Brooks"), new EmailAddress("[email protected]"));

e.sendTo(...)
...

This last code snippet looks like a lot more work than before both for me as a developer, the compiler and the runtime environment. The problem is really with th example. With a well constructed set of domain objects the Name and EmailAddress objects will be fields in some entity - possibly Account. The compiler might be doing a little more work but that work is in my interests - checking the types.

Email address format verification can now be put where it should be - in the EmailAddress class.

You can probably guess that Value types should be:

  • Small

  • Immutable

Values should be constructed at the boundaries of the system. Strings → EmailAddresses. Within the domain methods manipulate the value objects - not the data stored in them …​