We adopt a principle ‘Avoid Mutable State’ and prefer Functional Programming Code to Object Orientated Code. These two practices leads to heavy use of value objects. A value object is basically a data structure that holds data, and has no (or minimal) behavior. It has three fundamental characteristics: immutability, value equality and self validation.

Please note that some definitions of value object do not include that the object must be immutable. We have a policy ‘Avoid Mutable State’ which means that our value objects are immutable.

With the need to support parallelisation it has become clear that the basic object orientated memory model supports multi-threading very poorly. Almost all approaches to multi-threading separate out the data being manipulated into ‘value objects’ and have code that manipulates these value objects.

Value objects are very helpful in writing easily testable code. Much of our code can be a function that takes one or more (preferably one) value objects and returns another value object.

Advice

Advice Why
Don’t use getters : expose read only fields Unless you really need the getters all that the ‘getXXX’ methods do is add a place that you can make a mistake in and introduce a bug. And these bugs happen so if you have getters you need to test them
Don’t use setters: use constructor creation ‘Avoid Mutable State’, and writing test code is a lot simpler. And if you add setters you need to test them
implement equals and hashcodes using libraries, not manually (e.g. lombok or scala case classes) Most implementations of hashcode and equals have bugs. Even if generated by an IDE, when fields are changed these need to be added and people forget to update the code
Use value objects instead of primitives where ever possible Even if the value object has one field you gain the benefit of strong types. This is often known as the

Links

For those interested in the philiosophy of value objects