Reference Objects and Value Objects

Reference Objects and Value Objects

One of the common things said about objects is that they have identity. This is true, but it is not quite as simple as that. In practice, you find that identity is important for reference objects, but not so important for value objects.

Reference objects are things like Customer. Here, identity is very important, because you usually want only one software object to designate a customer in the real world. Any object that references a Customer object will do so through a reference or pointer; all objects that reference this Customer will reference the same software object. That way, changes to a Customer are available to all users of the Customer.

If you have two references to a Customer and you wish to see whether they are the same, you usually compare their identities. Copies may be disallowed; if they are allowed, they tend to be made rarely, perhaps for archive purposes or for replication across a network. If copies are made, you need to sort out how to synchronize changes.

Value objects are things like Date. You often have multiple value objects representing the same object in the real world. For example, it is normal to have hundreds of objects that designate 1-Jan-99. These are all interchangeable copies. New dates are created and destroyed frequently.

If you have two dates and you wish to see whether they are the same, you don't look at their identities, but rather at the values they represent. This usually means that you have to write an equality test operator, which for dates would make a test on year, month, and day (or whatever the internal representation is). Usually each object that references 1-Jan-99 has its own dedicated object, but you can also share dates.

Value objects should be immutable (frozen; see "Frozen" on page 95). In other words, you should not be able to take a date object of 1-Jan-99 and change the same date object to be 2-Jan-99. Instead, you should create a new 2-Jan-99 object and link to that first object. The reason is that if the date were shared, you would update another object's date in an unpredictable way.

In days gone by, the difference between reference objects and value objects was clearer. Value objects were the built-in values of the type system. Now you can extend the type system with your own classes, so this issue requires more thought. Within the UML, attributes are usually used for value objects, and associations are used for reference objects. You can also use composition for value objects.

I don't find that the distinction between reference and value objects is useful with conceptual models. It can cause confusion with multiplicities. If I represent a link to a value object with an association, I usually mark the multiplicity of the end on the user of the given value as *, unless there is a uniqueness rule, such as a sequence number.