Singleton Pattern

Singleton Pattern

The singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is
useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects.

Common uses

  • The Abstract Factory, Builder, and Prototype patterns can use Singletons in their implementation.
  • Facade Objects are often Singletons because only one Facade object is required.
  • State objects are often Singletons.
  • Singletons are often preferred to global variables because:
    • They do not pollute the global name space (or, in languages with namespaces, their containing namespace) with unnecessary variables.
    • They permit lazy allocation and initialization, whereas global variables in many languages will always consume resources.

Implementation

Implementation of a singleton pattern must satisfy the single instance and global access principles. It requires a mechanism to access the singleton class member without creating a class object and a mechanism to persist the value of class members among class objects. The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist. If an instance already exists, it simply returns a reference to that object. To make sure that the object cannot be instantiated any other way, the constructor is made private. Note the distinction between a simple static instance of a class and a singleton: although a singleton can be implemented as a static instance, it can also be lazily constructed, requiring no memory or resources until needed. Another notable difference is that static member classes cannot implement an interface, unless that interface is simply a marker. So if the class has to realize a contract expressed by an interface, it really has to be a singleton.
The singleton pattern must be carefully constructed in multi-threaded applications. If two threads are to execute the creation method at the same time when a singleton does not yet exist, they both must check for an instance of the singleton and then only one should create the new one. If the programming language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.
The classic solution to this problem is to use mutual exclusion on the class that indicates that the object is being instantiated.

Example

The Java programming language solutions provided here are all thread-safe but differ in supported language versions and lazy-loading. Since Java 5.0, the easiest way to create a Singleton is the enum type approach, You could find at the end of this section.

Lazy initialization

This method uses double-checked locking, which should not be used prior to J2SE 5.0, as it is vulnerable to subtle bugs. The problem is that an out-of-order write may allow the instance reference to be returned before the Singleton constructor is executed

public class Singleton {
	private static volatile Singleton instance = null;

	private Singleton() {
	}

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

Eager initialization

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

	private Singleton() {
	}

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

If the program will always need an instance, or if the cost of creating the instance is not too large in terms of time/resources, then can switch to eager initialization, which always creates an instance:

This method has a number of advantages:

  • The instance is not constructed until the class is used.
  • There is no need to synchronize the getInstance() method, meaning all threads will see the same instance and no (expensive) locking is required.
  • The final keyword means that the instance cannot be redefined, ensuring that one (and only one) instance ever exists.

This method also has some drawbacks:

  • If the program uses the class, but perhaps not the singleton instance itself, then you may want to switch to lazy initialization.

Static block initialization

public class Singleton {
	private static final Singleton instance;

	private Singleton() {
		// ...
	}
	static {
		instance = new Singleton();
	}

	public static Singleton getInstance() {
		return instance;
	}

}

This solution allowing some pre-processing (e.g. for error-checking). In this sense, the traditional approach could be seen as a particular case of this one, as the class loader would do exactly the same processing.

The solution of Bill Pugh

The technique known as the initialization on demand holder idiom, is as lazy as possible, and works in all known versions of Java. It takes advantage of language guarantees about class initialization, and will therefore work correctly in all Java-compliant compilers and virtual machines. The nested 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).

public class Singleton {
	private static final Singleton instance;

	private Singleton() {
		// ...
	}
	static {
		instance = new Singleton();
	}

	public static Singleton getInstance() {
		return instance;
	}

}

Alternatively, the inner class SingletonHolder can be also substituted by implementing a Property which provides also access to the static final/read-only class members. Just like the lazy object in C#, whenever the Singleton.INSTANCE property is called, this singleton is instantiated for the very first time.

The Enum way

This technique defines “a single-element enum type is the best way to implement a singleton for any Java that supports enums. The use of an enum is very easy to implement and has no drawbacks regarding serializable objects, which have to be circumvented in the other ways.

Example: Create Singleton enum class:

public enum SingletonEnum {
	INSTANCE;

	public void doSomethingInSingletonEnumFactoryClass() {
		System.out.println("Do something in this method.");
	}

}

Now implement singleton pattern in a class:

public class EnumSingletonImplementation {
	public static void main(String[] args) {
		SingletonEnum singletonEnum = SingletonEnum.INSTANCE;
		singletonEnum.doSomethingInSingletonEnumFactoryClass();
		// doesn't compile :
		// SingletonEnumFactory sngletonEnumFactory2 = new
		// SingletonEnumFactory();
	}
}

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.

 

  • That’s it. Below is list of all design patterns link:

Creational Patterns:

Structural Patterns:

Behavioral Patterns:

 

Leave a Reply

Your email address will not be published. Required fields are marked *