3 Reasons to Use Immutable Objects

Have you ever had to debug a weird, inconsisten problem that ended up being a race condition?  Perhaps you had an object that got into an invalid state?  Have you had an object grow and grow until memory has been exhausted?

If you answered yes to any of these questions, the solution may be immutable objects.

Immutable objects, as the name implies, are objects that cannot be modified after they are created. This is often enforced by making class member variables private—hiding the implementation from those using the class (which is a good practice anyway). Many languages can go a step further. In Java, the final keyword is used to prevent member fields from modification. Javascript has readonly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SomeClass {
private final String _name;
private final int _count;

public SomeClass(String name) { this(name, 0); }

private SomeClass(String name, int count) {
this._name = name;
this._count = count;
}

public SomeClass increment() {
return new SomeClass(this._name, this._count + 1);
}

public String getName() { return this._name; }
public int getCount() { return this._count; }

}

The result is all the same: the object must be initialized at construction time. Any changes results in the creation of a new instance.

Why go through all the trouble?

There are three main benefits to using immutable objects: concurrency, memory and validation.

Concurrency

Most issues in a multithreaded application result from several threads attempting to modify the same piece of data at the same time. Elaborate locking and synchronization mechanisms are constructed in order to prevent the standard problems with thread contention (deadlock, starvation, live lock, race conditions, etc.), but these can be difficult to implement correctly and may slow down your application.

Single threaded applications are not immune from contention either (I’m looking at you, Javascript). As soon as your application awaits on an asynchronous process, you’ve introduced the possibility for something to mutate the state of an object in an unexpected way.

Immutable objects remove most, if not all, of this complexity.  Since the state of the object cannot be changed, no locking is necessary.

Memory

Most garbage collection systems, such as the Java Virtual Machine, love short-lived, immutable objects. These object tend to get created, recreated and discarded fairly quickly. After all, you want your application to do something.

Short-lived objects are cleared from memory pretty quickly and don’t often make it into the old, tenured memory space. This means that the garbage collector is able to keep your memory usage under control and avoid frequent, stop-the-world garbage collection pauses in the application.

Validation

While there are definitely benefits with respect for concurrency and memory, one of the the main benefits of immutable object is that you are assured that an object is always in a known, good, consistent state.

An immutable object requires that you pass all of the required information when the object is constructed. Any “change” involves creating a new object based on the old object and passing in any new or updated information to the new version.

This means that you cannot end up with an object in a partially constructed state.

Knowing that your object is in a good state makes your code simpler, easier to read and less likely to have bugs that are hard to track down.

Conclusion

Immutable objects can help avoid concurrency issues, improve the memory management and reduce bugs and complexity in your application.

In your next project, try using immutable objects and I think you’ll be happy you did!

Question: What benefits do you see from using immutable objects?