Samstag, 7. August 2010

Simpler Java #5: Use Immutables

Note: I want to show some simple programming concepts which are easy to follow and result in simpler java code. All the while, I will never break with the default java coding style, so even developers not aware of these "techniques" can still easily read your code.

An immutable object is defined as an object of which all accessible fields available members are set final (so only getters are available) and are immutable themselves. Modification of the values is usually achived by copy on write: Create a new instance with 1 or more modified values. You cannot change them in-place, but you can have variables which hold different immutables during the flow of a method. This is exactly the behavior of the string class, so you will know the concept already.

#1 Immutability counts only for the public interface
Its still allowed to have mutable fields and mutable objects within an immutable. However, the may not be accessible from the outside world in any way which exposes this fact. Even further, the outer world may never be allowed to give these values even on construction! (As they could change them later and break with the immutability. So, having a mutable list with mutable values for some reasons is ok, as long as neither of these can be accessed in such a way from the outside which would permit a mutation.
In general: Immutability must be guaranteed for public and protected scope only. Its completely ok to achieve internal modifications on package-private and private level as long as they are reasonable, of course, and mostly only ever for performance tricks. Note, however, that all these modifications may never change the return values of the object in any way NOR break with its thread-safety, so this is not an "all-in"!.

#2. Immutability allows optimization
See wikipedia and other sources for details on this. Copy-On-Write might seem like a limitation, but especially for small objects its nearly always worth it, esp. since you can reuse objects in multiple contexts, which often saves you from creating an equal instance over and over.

#3. Immutability should not be designed for inheritance.
Simple one. Even though inheritance is possible, you should not allow it unless it is really needed. Make the class final or give it a public constructor. The advantages of inheritance are seldomly needed, and unless you need them you should not risk it to screw everything up if someone introduces a mutable subclass of your immutables. Note that this setting immutables final is commonplace in even in the jdk: Both String and the primive wrappers are all final, after all.

#4 Immutable objects should have a hidden constructor and rely on a factory method or a builder instead.
See the java builder pattern (effective java) for details. In general, factory methos or the builder pattern are always prefereable, since you sometimes want to decide wether you really need to create a new instance.  Immutables can be cached, so with a factory, you can introduce a caching technique later if you need them.
One the bigger flaws in the jdk primitive wrappers is that they all have public cons, which everyone use, even though there is a factory method (valueof), which can nearly always skip the creation for small int values and the like
Learn from this: Create the factory method right off the bat, and give it a simple and inituitive name. "of" should be always preffered for its conciseness.

Keine Kommentare:

Kommentar veröffentlichen