Me and a colleague are having a debate:
We have a singleton class that is used at multiple places in our code base.
Originally, the class was designed in such a way that you could get the class object but that object would not be completely initialized.
By this I mean:
mySingleton.getInstance().SomeMethod();
SomeMethod
would cause errors because the class was not initialized. For the class to work properly, this would have to happen:
mySingleton.getInstance().initObject();
mySingleton.getInstance().SomeMethod();
Anyways, the debate I have is that the constructor (called with the first get instance) should call initObject
so that no errors can be thrown.
What do you think?
My colleague likes it the other way so he knows when the class is getting initialized. (i.e. he calls initObject
at 1 specific line of code and hopes that nothing else needs it first).
There is a private field which actually holds the reference to the singleton. NULL is a property which instantiates the singleton if not already instantiated and returns it.
Null Object is a concrete collaborator class that acts as the collaborator for a client which needs one. The null behavior is not designed to be mixed into an object that needs some do nothing behavior.
In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior.
Disadvantages of a Singleton PatternUnit testing is more difficult (because it introduces a global state into an application). This pattern reduces the potential for parallelism within a program, because to access the singleton in a multi-threaded system, an object must be serialized (by locking).
You're closer to the usual way that the singleton pattern is implemented in Java than your colleague. Please, take a look at Wikipedia. There you will find the 3 most common Java implementations:
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
// Private constructor prevents instantiation from other classes
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
public static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
public class Singleton {
// volatile is needed so that multiple threads can reconcile the instance
// semantics for volatile changed in Java 5.
private volatile static Singleton singleton;
private Singleton() {}
// synchronized keyword has been removed from here
public static Singleton getSingleton() {
// needed because once there is singleton available no need to acquire
// monitor again & again as it is costly
if (singleton == null) {
synchronized (Singleton.class) {
// this is needed if two threads are waiting at the monitor at the
// time when singleton was getting instantiated
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Neither of them make use of a separated initObject()
method (initialization is supposed to be inside the private constructor). Also notice that if you have a separated, public initObject()
method, you may have multi-threading issues...
BTW, personally I rather use the "Bill Pugh" alternative, but the 3 ways are valid.
Edit After the kind Esko comment, I'm adding the following implementation, which is not available on Wikipedia. I just would like to add that 1) The singleton instance is not lazily created like the 3 options above; 2) Since it is a enum, you cannot extend any class; and 3) It is very, very weird. But it seems to be quite hyped on the Java community, so it is here:
public enum Singleton {
INSTANCE;
Singleton() {
/* Your init code goes here */
}
}
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