Having come across the concept of immutable objects recently, I would like to know the best practices for controlling access to the state. Even though the object oriented part of my brain makes me want to cower in fear at the sight of public members, I see no technical issues with something like this:
public class Foo {
public final int x;
public final int y;
public Foo( int x, int y) {
this.x = x;
this.y = y;
}
}
I would feel more comfortable declaring the fields as private
and providing getter methods for each but this seems overly complex when the state is explicitly read only.
What is the best practice for providing access to the state of an immutable object?
The only real disadvantage of immutable classes is that they require a separate object for each distinct value. Creating these objects can be costly, especially if they are large. For example, suppose that you have a million-bit BigInteger and you want to change its low-order bit: BigInteger moby = ...; moby = moby.
No, it is not mandatory to have all properties final to create an immutable object. In immutable objects you should not allow users to modify the variables of the class. You can do this just by making variables private and not providing setter methods to modify them.
To put it simply, a class instance is immutable when its internal state can't be modified after it has been constructed. A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe.
The term Mutable means "can change" and Immutable means "cannot change". An Immutable Object means that the state of the Object cannot change after its creation. Here the String is immutable means that you cannot change the object itself, but you can change the reference to the object.
It depends entirely on how you're going to use the object. Public fields aren't inherently evil, it's just bad to default everything to being public. For example the java.awt.Point class makes its x and y fields public, and they aren't even final. Your example seems like a fine use of public fields, but then again you might not want to expose all of the internal fields of another immutable object. There is no catch-all rule.
I have thought the same in the past but usually end up making variables private and using getters and setters so that later on I'll still have the option of making changes to the implementation while keeping the same interface.
This did remind me of something I read recently in "Clean Code" by Robert C. Martin. In chapter 6 he gives a slightly different perspective. For example, on page 95 he states
"Objects hide their data behind abstractions and expose functions that operate on that data. Data structure expose their data and have no meaningful functions."
And on page 100:
The quasi-encapsulation of beans seems to make some OO purists feel better but usually provides no other benefit.
Based on the code sample, the Foo class would seem to be a data structure. So based on what I understood from the discussion in Clean Code (which is more than just the two quotes I gave), the purpose of the class is to expose data, not functionality, and having getters and setters probably does not do much good.
Again, in my experience, I have usually gone ahead and used the "bean" approach of private data with getters and setters. But then again, no one ever asked me to write a book about how to write better code so maybe Martin has something to say.
If your object is of local-enough usage that you don't care about the issues of breaking API changes for it in the future, there is no need to tack getters on top of the instance variables. But this is a general subject, not specific to immutable objects.
The advantage of using getters comes from one extra layer of indirection, which may come in handy if you are designing an object which will be widely used, and whose utility will extend into unforseeable future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With