The Value Object pattern provides the following general benefits:
- Better domain modeling and understanding. Recognizing a domain concept as a value type and implementing it as such reduces the gap between the domain model and its implementation. This eases code comprehension.
- Safer programs. Implementing value objects with immutable classes eliminates a whole class of bugs that comes from unwanted side-effects. Thus, your programs get safer.
- Potentially better performance. Value objects can improve system performance, because value objects are copied only if they are about to be changed. No superfluous copying happens.
There are more specific advantages, depending on where and how you use value objects.
- Concurrency. Because you can’t change a value object’s state, you don’t have to synchronize methods or lock the object in other ways. Hence, you improve performance.
- Persistence. Value objects don’t have to maintain an object id, hence you can directly write them to a relational database table without having to maintain them in separate tables with primary ids.
- Serialization. Similar to persistence, you can simply dump a value object as data into a data stream and you don’t have to worry about dangling references from other parts of the object graph being serialized.
- Distribution. Also, as you copy regular objects across process boundaries, you always copy enclosed value objects too---you never pass on references to value objects across process boundaries.
- Memory consumption and garbage collection. By sharing value objects (see below for a discussion), you can potentially safe a lot of memory and ease the burden on the garbage collector (like in the Flyweight pattern).
There are also some disadvantages.
- More complicated code. Value object classes require a little more code upfront than regular object classes. So clients need to understand that they are dealing with value objects, and need to look at how they are handled before using them.
- Changes in coding style. Programming with value objects may feel strange at first if you are not used to it. Effectively, you never change the state of a value object but rather assign a new value object to a client’s attribute, whenever you made a computation with that attribute.
- Potentially lower performance. Unqualified use of value objects may reduce system performance. In particular heavyweight value objects that go through computations where a lot of these objects are created and dropped quickly may drag down performance.
In a given system, if it would distinguish value types from regular classes cleanly, the majority of domain concepts would be value types rather than object classes.
Next