Home Articles Talks Links Contact Me ISA ThoughtWorks

Value Object


A small simple object, like a money or date range, whose equality is not based on identity.

In dealing with object systems of various kinds, I've found it useful to distinguish between reference objects and Value Objects. Of these two a Value Object is usually a small object, similar to the primitive types present in many languages that are not purely object-oriented.

How it Works

Defining the difference between a reference object and Value Object is often a tricky thing. In a broad sense we like to think of it that Value Object are small objects, such as a Money object or a date; while reference objects are larger things like orders and customers. Such a definition is handy, but annoyingly informal.

The key difference between a reference and value object lies in how they deal with equality. A reference object uses identity as the basis for equality. This may be the identity within the programming system, such as the built in identity of OO programming languages; or it may be some kind of ID number, such as the primary key in a relational database.

A Value Object bases it's notion of equality on field values within the class. So two date objects may be the same if their day, month, and year values are the same.

The difference manifests itself in how you deal with them. Since Value Objects are small and easily created, they are often passed around by value instead of by reference. You don't really care about how many March 18 2001 objects there are in your system. Nor do you care if two objects share the same physical date object, or whether they have different yet equal copies.

Most languages don't have any special facility for value objects. In these cases for value objects to work properly it's a very good idea to make any Value Object immutable. That is once created, none of its fields should change. The reason for this is to avoid aliasing bugs. An aliasing bug occurs when two objects share the same value object and one of the owners changes the values in the value. So if Martin has a hire date of Mar 18 and we know Cindy was hired on the same day, we may set Cindy's hire date to be the same as Martin's. If Martin then changes the month in his hire date to May, Cindy's hire date changes too. Whether it's correct or not, it isn't what people would expect. Usually with small values like this people would expect to change a hire date by replacing the existing date object with a new object. Making Value Objects immutable fulfills that expectation.

.NET

A pleasant exception to this is .NET which has a first class treatment of Value Object. In C# objects are marked as Value Object by declaring them as a struct instead as a class.

Value Objects shouldn't be persisted as complete records. Instead use Embedded Value or Serialized LOB. Since Value Objects are small Embedded Value is usually the best choice, since it also allows SQL querying using the data in the Value Object.

If you are doing a lot of binary serializing you may find that optimizing the serialization of Value Objects can have a big impact on improving performance, particularly in languages like Java that don't have special treatment for Value Objects.

For an example of a Value Object see Money.

When to Use it

Treat something as a value object when you are basing equality on something other than an identity. It's worth considering this for any small object that is easy to create.

Name Collisions

I've seen Value Object used in this style for quite a time. Sadly recently I've seen people use the term 'value object' to mean Data Transfer Object, something that caused a storm in the teacup of the patterns community. This is just one of these clashes over names that happen all the time in this business. I continue to use Value Object in this way in this text. If nothing else this allows me to be consistent with my own previous writings!



© Copyright Martin Fowler, all rights reserved