5
\$\begingroup\$

I've found more than one implementation of the Singleton Pattern in Java (more like 5-6). I want to know if both of the following snippets of code (written by me) are valid implementations of Singleton Pattern in Java.

//Eagerly intialization
public final class LoggerEagerSingleton {

private static final LoggerEagerSingleton logger = new LoggerEagerSingleton();

private LoggerEagerSingleton() {
}

public static LoggerEagerSingleton getInstance() {
    return logger;
}
}

//Lazy Initialization
public final class LoggerLazySingleton {

private LoggerLazySingleton() {
}

public static LoggerLazySingleton getInstance() {
    return LazyHelper.logger;
}

private static class LazyHelper {
    private static final LoggerLazySingleton logger = new LoggerLazySingleton();
}
}
\$\endgroup\$
  • 2
    \$\begingroup\$ Beside the technical part: Singelton are global variables. Therefore you should avoid using the singelton pattern. In case you really need a certain class to have only one instance at your programs runtime use other techniques (eg. a feature of a DI framework) to ensure this singularity. \$\endgroup\$ – Timothy Truckle Mar 6 '17 at 9:06
1
\$\begingroup\$

The singleton pattern guarantees that only one instance of a class will be created into the application context.

So, in your code I see that:

  • You are create a static final class.
  • You declare the selfclass propertie as final: private static final LoggerEagerSingleton logger

Both of these last points are not necessary because the singleton pattern guarantees that just one will be create and nobody could be modify the unique instance of the singleton class.

The singleton patterns suggest the following rules:

  • A private construct.
  • A Static private property of the self class.
  • A Static method to get the unique instance, where it create the instance if it has not been created.
 
    public class SimpleSingleton {

        private SimpleSingleton logger;

        private SimpleSingleton() {

        }

        public static SimpleSingleton getInstance() {

            if(logger == null)
                logger = new LoggerEagerSingleton();

            return logger;
        }
    }

 

As you can see the property logger is create in the static method getInstance() and no other methods give access or alter this property, and the method give you a way to get the unique instance of the class.

So if you apply these rules, your classes could be rewritten like:

public class LoggerEagerSingleton {

    private static LoggerEagerSingleton logger = null;

    private LoggerEagerSingleton() {
    }

    public static LoggerEagerSingleton getInstance() {
        if(logger == null)
            logger = new LoggerEagerSingleton();
        return logger;
    }

    //TODO: All the remain methods
    public void method A()
    {

    }

}

And it could be used as:

LoggerEagerSingleton ref = LoggerEagerSingleton.getInstance();
ref.void methodA();

But remember, a patter is a generic design that has been used to solve some issues that are common in several projects. So you can implement the pattern as it is presented or make some modifications without altering the essence of the pattern.

\$\endgroup\$
  • 2
    \$\begingroup\$ Beside the technical part: Singelton are global variables. Therefore you should avoid using the singelton pattern. In case you really need a certain class to have only one instance at your programs runtime use other techniques (eg. a feature of a DI framework) to ensure this singularity. \$\endgroup\$ – Timothy Truckle Mar 6 '17 at 9:05
  • 1
    \$\begingroup\$ labelling the final keyword as unnecessary is simply incorrect and dangerous advice. Also your LoggerEagerSingleton is lazily initialized, which makes it all the more ironic to name it that way ... \$\endgroup\$ – Vogel612 Mar 6 '17 at 11:14
  • 2
    \$\begingroup\$ This kind of lazy assignement can provide two instances in a multithreaded system. There are other patterns to create a singleton and the more secure on is the usage of enum for which the uniqe instance is guaranted by the JVM. stackoverflow.com/questions/26285520/… \$\endgroup\$ – gervais.b Mar 6 '17 at 12:09
  • 1
    \$\begingroup\$ @ovidiu-miu your lazy version is not lazy. The instance is bound to your helper field that you reference when needed. In fact both of your samples are almost identical except the lazy one that add one inner class without benefits. If you want à lazy one you need the famous 'instance==null' but to removes the multithread risk you should add some synchronisation. Again for your knwoledge this is fine but remember that the singleton is an antipattern that cause much more than it solve \$\endgroup\$ – gervais.b Mar 6 '17 at 15:49
  • 1
    \$\begingroup\$ @gervais.b I think that's not true. The inner class technique is inspired from goo.gl/BXQIVK. "The Initialize-on-demand-holder idiom is a secure way of creating a lazy initialized singleton. It takes advantage of language guarantees about class initialization, and will therefore work correctly in all Java compilers and VMs. The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized)." \$\endgroup\$ – ovidiu-miu Mar 19 '17 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.