Developers around the world have embraced object-oriented programming paradigm in order to create quality applications. But while trying to model complex structures and behaviors, somehow we forgot to appropriately represent simple values. That’s where value objects come into play.

About Value Objects

Martin Fowler defines value object (VO) in the following way: A small simple object, like money or a date range, whose equality isn’t based on identity. So two value objects are equal not when they refer to the same object, but when the value that they hold is equal, e.g. two different one hundred dollar bills have the same value when we use them to buy something (class Money would be a value object). On the other side we have entities that are compared on identity, e.g. two people can have the same name, but are not the same person (class Person would be an entity), therefore are not equal. It’s very important to note that whether something should be represented as a value object or an entity, depends on the context it’s used in. Let’s look at the Money value object from our first example. For the government it might be considered as an entity, where each bill is differentiated by its serial number.

Example of simple value object:

PHP

Java

Example of simple entity:

PHP

Java

Of course in a real application Person would probably have some identity other than object’s reference (e.g. Social Security number).

 

We often hear about value objects in the context of Domain Driven Design (DDD in short) building blocks. And while I encourage everyone to get familiar with DDD concept, value objects are not tied to DDD and can be used outside of it.

Using Value Objects

In practical terms you can think of value objects as your own primitive types. And they should behave as ones. It means that value objects should always be immutable! This is crucial for languages that don’t support custom value types (e.g. PHP, Java), otherwise it’s hard to avoid issues with values changing unexpectedly (values should be replaced, not modified!).

When should value objects be used? Basically every time we have some value that has a special meaning in our business logic, even when it could be represented by a primitive type and especially if there are some limitations on the value it’d hold. For example email address can be represented by a simple string, but it’s better to use a value object (I’ll list all benefits of VOs a bit later, so keep reading!). And of course our value object can have more than one internal values (like in Money class example where we store both value and currency).

In addition to standard getter methods for internal state retrieval, VOs can have helper methods with various functionality. This includes creating new values (either entirely new or based on the current one, e.g. result of adding some amount to Money object), providing different representation for its internal state (e.g. IPAddress VO can present IP address as string or binary data), checking if value object meets some condition (e.g. DateRange VO can have a method to find out if it overlaps another DateRange object), etc. It’s important to remember about immutability (none of these methods can modify internal state) and to not to put any actual business logic inside value objects – they should be as self-contained as possible.

Example of additional VO method:

PHP

Java

Making it shorter

Unfortunately, as we can see in our Money examples, defining value objects requires quite a lot of additional code in some languages. While in case of PHP it’s not that bad and can be easy to overcome with use of modern IDEs, in Java even the simplest value object definition can look somewhat complex due to necessity of reimplementing standard equals and hashCode methods (in the example above Google’s Guava library is used to compute the hashCode result). Of course we still can leverage IDE and code templates, but there are some better alternatives.

Project Lombok Value – probably the most popular way to create value object classes in Java. It’s easy to use and the resulting code is very short:

Java

There are some shortcomings though – you can read about them in the AutoValue presentation linked in the next section.

Google AutoValue – another option to make definition of value objects in Java a lot simpler is AutoValue. It requires a bit of setup, but results in much cleaner and more readable code:

Java

To learn more I recommend checking out AutoValue: what, why and how? presentation.

Kotlin data classes – this is the best solution in my opinion. Since Kotlin has 100% Java interoperability we can add it with ease to existing Java projects. We can’t get anything much simpler than this:

Kotlin

If you want to know more about Kotlin and data classes see our Yet Another Kotlin Tutorial for Android Developers – Part 2 blog post (which is great not only for Android developers).

Validation

When creating a new value object we need to make sure that it has a valid state. Let’s take currency from our Money example. Right now we’re using primitive string type to represent it. But we know that it should always consist of three uppercase letters, so why not to convert it to its own VO:

PHP

Java

Here we only make sure that currency code has a correct format, but we could also validate it against ISO 4217 currency list (or its subset).

 

The validation that takes place in a value object should only be concerned with the value itself and should ensure that its state is valid. For example, EmailAddress VO should validate if given string is a correct email address, but shouldn’t check if this address is blacklisted in our application.

Persistence

Another place that will require some extra code when working with value objects is persistence of entities that use them. Fortunately the most popular ORMs for both PHP and Java (like Doctrine ORM and Hibernate ORM) support embedding of VOs which makes them easy to configure and reuse across entities. For examples see Doctrine ORM and Hibernate ORM documentation pages.

Value objects - software development php, java, kotlin

Benefits

There are a few substantial benefits of using value objects:

  • Readability – the types of things that we pass to different parts of our application match to what they represent in our domain and it’s clearer what kind of value is expected without having to check in the code
  • Validation – every existing value object is in a correct state. This means that we don’t have to check them when we use them (of course they still need to conform to our business rules)
  • Type hinting (for PHP < 7.0) – while in PHP 7.0+ we can type hint primitive types for parameters, it’s only possible for class types (which VOs are in PHP) in older versions
  • Immutability – value objects’ definition doesn’t require them to be immutable, but in practice immutability is needed… which is great, because immutability brings thread safety and makes the code easier to reason about (which means less bugs)

Untapped value

Value objects are quite simple both in concept and implementation, yet can make any codebase more readable and organized. Like most good patterns they require some additional work and getting used to, but the initial time investment will save you and your team a lot of work in the future. So leave primitives behind (where it makes sense) and start using value objects today!

Back-end Developer

Java/PHP developer. Interested in domain-driven design approach, distributed computing using Akka and modifying the Java compiler for fun.