Interning

For a value object state and identity are the same. For a reference object state and identity are distinct. (This is discussed in greater detail in the lecture: State and Identity.)

Problem

Logically, it doesn't matter if we have distinct value objects that have the same state, but it wastes memory.

Synchronization errors can occur if we allow distinct reference objects to refer to the same domain object.

Solution

Value objects can only be created by a static factory method. Given an initial state, the factory method first searches a value repository to determine if a logically identical object already exists. If so, then this object is returned. Otherwise, a new object is created, "interned" in the repository, and then returned to the caller.

Example

A symbol is a value object. The state of a symbol is its name. Two symbols are logically the same if they have the same name. To save memory, we wish to avoid having physically distinct, logically equivalent symbols.

See:

Symbol.java

Console.java

Note that while the performance is the same regardless of the value of the intern flag, fewer symbols get created when the flag is true.

Example: Managing Reference Objects (Rigid Designators, Essences)

Interning can be useful for reference objects, too. In this case we want to prevent creation of multiple objects that refer to the same domain object.

For example: Person objects have a mutable attribute: address. This makes it dangerous to have multiple instances referring to the same person.

We follow the interning pattern:

Now the constructors for Customer and Employee must call the static factory method:

class Customer {
   private Person actor;
   public Customer(String name, ???) {
      actor = Person.makePerson(name, ???);
   }
   // etc.
}

class Employee {
   private Person actor;
   public Employee (String name, ???) {
      actor = Person.makePerson(name, ???);
   }
   // etc.
}

 

Of course a problem arises when two customers or a customer and employee have the same name. To be correct, we need to have some way of uniquely identifying a person (the ??? parameter). Is there a way to do this? We could add a unique id number. This might be a person's Social Security number, but this won't work for people (children and foreigners) who don't have such a number. A made-up id number won't work because a person wouldn't be able to supply the Customer or Employee constructors with this number.

Related Patterns

Flyweight

Singleton