Wednesday, 7 August 2013

Creational Design Patterns -> Singleton Pattern


Motivation:
Sometimes it's important to have only one instance for a class. For example, in a system there should be only one window manager (or only a file system or only a print spooler). Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.
The singleton pattern is one of the simplest design patterns: it involves only one class which is responsible to instantiate itself, to make sure it creates not more than one instance; in the same time it provides a global point of access to that instance. In this case the same instance can be used from everywhere, being impossible to invoke directly the constructor each time.

Intent:
•    Ensure that only one instance of a class is created.
•    Provide a global point of access to the object.

Single Pattern ensures following things.
•    It ensures that instance is created only once.
•    It ensures that instance will never be null.
•    It ensures that instance will be thread safe.
•    Instance uses little memory.
•    Provides lazy instantiation.
•    Class is freezes for sub-classing and instantiation.


Static
Singleton
It has only static methods, for which a better word would be "functions". The design style embodied in a static class is purely procedural.
is a pattern specific to OO design. It is an instance of an object (with all the possibilities inherent in that, such as polymorphism), with a creation procedure that ensures that there is only ever one instance of that particular role over its entire lifetime.

static member classes cannot implement an interface, unless that interface is simply a marker.
if the class has to realize a contract expressed by an interface, it really has to be a singleton.




Usage: classes that basically does conversions,utility functions. please check Math class.
Usage: classes that serve as global configuration , ex: Trial version of software with one database connection, JDK Runtime classes instances per jvm.
helper classes, used by all the classes in your api development.
When to go: 1.While developing your code,you think of forward compatibilty, like tomorrow when you need to convert this singleton class to normal class or allow subclassing. 2. You can provide lazy loading feature , when this singleton class is heavy.
Eager Loading
Lazy loading (requiring no memory or resources until needed)
java.lang.Math 
java.lang.Runtime
Static class provides better performance than Singleton pattern, because static methods are bonded on compile time.
On the other hand, you can override methods defined in Singleton class by extending it.





Lazy initialization:
public class SingletonDemo {
        private static volatile SingletonDemo instance = null;

        private SingletonDemo() {       }

        public static SingletonDemo getInstance() {
                if (instance == null) {
                        synchronized (SingletonDemo .class){
                                if (instance == null) {
                                        instance = new SingletonDemo ();
                                }
                      }
                }
                return instance;
        }
}



Eager initialization:
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}



Enum Way (from Java 5 onwards)
public enum Singleton {
        INSTANCE;
        public void execute (String arg) {
                //... perform operation here ...
        }
}


This approach implements the singleton by taking advantage of Java's guarantee that any enum value is instantiated only once in a Java program. Since Java enum values are globally accessible, so is the singleton. The drawback is that the enum type is somewhat inflexible; for example, it does not allow lazy initialization.

Using serialization, single instance contract of the singleton pattern can be violated. You can serialize and de-serialize and get a new instance of the same singleton class. Using java api, you can implement the below method and override the instance read from the stream. So that you can always ensure that you have single instance.
readResolve()


Examples:
•  Java.lang.Runtime with getRuntime() method
•  Java.awt.Toolkit with getDefaultToolkit()
•  Java.awt.Desktop with  getDesktop()

Note: Double checked locking is a technique to prevent creating another instance of Singleton when call to getInstance() method is made in multi-threading environment. In Double checked locking pattern as shown in below example, singleton instance is checked two times before initialization.

Hot Spot:
•    Multithreading - A special care should be taken when singleton has to be used in a multithreading application.
•    Serialization - When Singletons are implementing Serializable interface they have to implement readResolve method in order to avoid having 2 different objects.
•    Classloaders - If the Singleton class is loaded by 2 different class loaders we'll have 2 different classes, one for each class loader.
•    Global Access Point represented by the class name - The singleton instance is obtained using the class name. At the first view this is an easy way to access it, but it is not very flexible. If we need to replace the Sigleton class, all the references in the code should be changed accordinglly.

Sources: Wikipedia, OODesign, TutorialsPoint, Javarevisited

2 comments:

  1. I think it is a good share about singleton pattern but there is more at this adress Singleton Pattern in Java

    ReplyDelete