Immutable Design Pattern

I am sure a lot of java developers have heard of String being immutable in Java. But what are the advantages of making a certain object immutable or when should we make an object immutable and most importantly how do we make objects immutable? These are some of the questions that I always answer when mentoring new java developers.

I always wanted to document the answers so that a major portion of developers can benefit from this pattern. Lets answer these questions one by one. So the first up we should define what exactly is immutability. Heres a perfect definition: An immutable object is one that, after creation, is `read-only’; it cannot be changed; none of its methods changes it. This defines immutability perfectly. The String class in java and all the primitive wrappers like Integer, Long etc. are immutable.

But what advantages will it give if we can’t change the object after it’s creation. Ever seen developers using the + operator for string concatenation and the look on their faces when they get to know that they have managed to load test the Garbage Collector with their simple piece of code . Anyways back to the question. The main advantage of immutability is that you can easily cache the object w/o worrying about cache poisoning or objects getting changed in the cache when someone changes the object returned from it. Remember the String class is cached so are all the wrapper classes to a certain limit.

This also answers our second question i.e., whenever you want to cache objects make them immutable.

Lets move on to the last question. How to make objects immutable? The simplest answer that people always come up with is not creating any mutators (setters) for the object so that you create the object using a constructor or a factory and you can never modify the object. But thats not totally true. In case your object only contains primitives which are passed by value this technique will work but in case the object contains other objects which are passed by reference then you have a serious flaw in your implementation. There are two cases that need to be handled.

  1. What to do when the object is passed in while constructing our immutable object?
  2. What to do when returning these objects using the accessors (getters)?

The only solution that comes to mind is to make a defensive copy of these objects whenever they are passed or passed out. Okay what else? can anyone think of any other pitfalls. Well there is one more. You should always make your immutable class final. The reason being we don’t want it to be sub-classed, Why? because if you do you can very easily modify the state of the object if they are declared protected. But what if they are declared as private? Even in that case it is pretty easy to break the contract and give the impression that the object is immutable when its not. Reason why the String class is also declared as final

What to do if we want to modify the object? According to the discussion above it seems like we are not providing any mutators and the only solution that remains is to explicitly construct a new object with the modified values. Well there are two solutions

  1. Provide mutators(setters) for the object. But instead of following the normal mutator pattern of returning nothing we return the new object with the changed values.
  2. Provide a separate class which allows us to modify our object. Take the example of String and the StringBuffer/StringBuilder class. When we want to modify a String w/o creating temporary objects we use StringBuffer/StringBuilder class and when we are done we call its toString method to get the String object with our desired value.

The latter approach is quite helpful as it allows a simple method to make modifications on the immutable object w/o breaking the contract of immutability and doesn’t even creates the temporary objects.

Lets summarize the whole pattern in few points:

  1. Make sure the immutable class is declared as final.
  2. If only primitives are used in the immutable class then we can skip all the mutators and just provide the accessors.
  3. In case the immutable class contains other objects, make defensive copies of these objects whenever they are passed in through the constructor and passed out using the accessors.
  4. In case there is a need for modifying the object state w/o creating many temporary objects provide a separate mutator class to do the job.
  5. Also declare all the fields final. It is good for two reasons, it saves you from accidentally changing the value and there is a compile time error if you forget to initialize it. final is your fiend, use it. Thanks Ben for the suggestion.

Always make objects immutable when you want to cache them. This will save you from lots of hard to find bugs. Trust me I have been through it and I know how difficult it is to debug these issues in production environment when customers/management is screaming at you to get them resolved in hours.

As a final note there is one more way to make the object immutable. Plain old documentation to the rescue. Just document clearly that the object shouldn’t be modified after its creation for the correct working  But I guess thats an ideal solution where every developer follows what the documentation says or just even reads it  

Immutable Design Pattern

13 thoughts on “Immutable Design Pattern

  1. Ben says:

    You should also make all fields final, which not only communicates to other developers its immutable but forces it to be so for the compiler. While not strictly required, it ensures no sloppy mistakes.

  2. anonymous says:

    Do you know what is the purpose of declaring a field “final”. That means once you assign a value to it, you can never change it. I don’t know what is the use of final for fields when you want to make something immutable.

  3. Ben says:

    I believe this is discussed in “Java Concurrency in Practice”, but my copy is on loan and I read it over a year ago. So we’ll go by my memory, which being repeatedly stuffed full of arcane knowledge, is probably wrong!

    One of the main values of making an object immutable is that it is inherently threadsafe. Multiple threads can safely read the data without synchronization (which, remember, must be on both _reads_ and _writes_). If a field is not static, volatile, or final, then it can be re-ordered by the compiler. The compiler, just like hardware OoO dispatching, simply guarrenties to the developer that the same behavior will occur. The order of operations, though, may be changed singnificantly to increase performance. In single-threaded code, this is easy to guarrenty. However, in concurrent code the compiler needs a few hints. By forcing ordering, you ensure that the object’s reference is not leaked out to another thread before construction completes (as shown with DCL on singletons).

    So, basically, final fields force ordering for loads/stores on dependancies which reduces race conditions. Its good practice in general, simply by using the rule of thumb that you start with a strong contract and weaken as required. It also provides miniscule performance improvements, which you should never ever consider, by allowing a few more optimization tricks.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s