Version 2 (modified by hauma, 15 years ago) (diff)

Matrix example added.

The Value Pattern

The Value pattern is a meta-pattern summarizing all approaches to express all kind of data in an object oriented language that does not require all properties of first-class objects.

Objects with identity

Besides encapsulated state that is accessed through the objet's methods, a first-class object has an identity. This identity is unique for each created object. It distinguishes an object from all other objects, no matter whether those objects are instances of the same class, or encapsulate exactly the same state.

In Java, two objects (object references) a and b are identical, if the (non-overloadable) operator == returns true for the comparision a == b. Another way how the identity of objects can be revealed, is their usage as locks in synchronization operations. Two variables refer to identical objects, if no concurrent access to regions synchronized (a) {...} and synchronized(b) {...} is granted.

Objects without identity

Values do not (should not) have such identity. Two values are identical, if they behave equally. E.g., it makes no sense to use values as locks in synchronization primitives.

Value example

A class for representing matrices with operations "add", "invert", "scalarMultiply" and "matrixMultiply" should serve as example for a typical value class. Two matrix objects should considered identical, if they represent the same mathematical object.

There are two opposed approaches for implementing value classes. One is the mutable value class and the other is the immutable value class.

Mutable value class

Let us first consider the mutable value class approach. Typical signatures of the methods would look like in the following figure:

class Matrix {
   void add(Matrix that, Matrix result);
   void invert(Matrix result);
   void scalarMultiply(double factor, Matrix result);
   void matrixMultiply(Matrix that, Matrix result);

When programming in the mutable value class style, the caller of an operation can provide storage for result value. This is considered commonly most efficient, because the client can decide, whether storage allocation is required. This reduces unnecessary temporary storage allocation.

Immutable value class

In the immutable value class style, each operation returns a fresh allocated matrix object. This is necessary, because a matrix once created cannot be modified any longer. A matrix class with the same operations but formulated in the immutable value style would look like in the following figure:

class Matrix {
   Matrix add(Matrix that);
   Matrix invert();
   Matrix scalarMultiply(double factor);
   Matrix matrixMultiply(Matrix that);