Singleton Pattern   «Prev  Next»
Lesson 14

Singleton Design Pattern Conclusion

In this module, you learned about the Singleton design pattern. The Singleton pattern is a creational pattern that lets you create a single instance of the class and provides and controls access to it through a public static method. A nonpublic constructor prevents clients from creating new instances of the class. The Singleton pattern is used to ensure that only one object of a particular class is instantiated. The Singleton pattern is used for single-threaded applications.

Review the Primary Elements that make up the Singleton Pattern in Software Development

The Singleton Pattern is a creational design pattern that ensures a class has only one instance while providing a global point of access to it. This is particularly useful when exactly one object is needed to coordinate actions across a system.
Here are the "primary elements" that make up the Singleton Pattern:
  1. Private Constructor
    • The constructor is declared private to restrict instantiation of the class from outside.
    • This ensures that the class cannot be instantiated using the new keyword from other classes.

          public class Singleton {
            private Singleton() {
              // Private constructor
            }
          }
        
  2. Static Instance Variable
    • A static variable holds the single instance of the class.
    • This is the core of the pattern, as it stores the instance that will be shared across all requests for it.
    • Eager Initialization: The instance is created at the time of class loading.
    • Lazy Initialization: The instance is created only when it is first accessed.
          private static Singleton instance;
        
  3. Public Static Access Method
    • A public static method provides a global point of access to the instance.
    • It returns the same instance every time it is called, ensuring that only one instance exists.
          public static Singleton getInstance() {
            if (instance == null) {
              instance = new Singleton();
            }
            return instance;
          }
        
  4. Thread Safety (Optional)
    • In multithreaded environments, thread safety must be ensured to prevent multiple threads from creating separate instances.
    • Solutions include:
      • Using the synchronized keyword for the access method.
      • Implementing double-checked locking.
      • Leveraging the Initialization-on-Demand Holder idiom in Java.
          public class Singleton {
            private static volatile Singleton instance;
    
            private Singleton() {}
    
            public static Singleton getInstance() {
              if (instance == null) {
                synchronized (Singleton.class) {
                  if (instance == null) {
                    instance = new Singleton();
                  }
                }
              }
              return instance;
            }
          }
        
  5. Global Access Point
    • The Singleton pattern ensures there is a global and consistent way to access the instance.
    • Typically, the static getInstance() method acts as this access point.
  6. Optional Enhancements
    • Serialization Safe Singleton:
      • To prevent a new instance from being created during deserialization, implement the readResolve method.
                private Object readResolve() {
                  return getInstance();
                }
              
    • Cloning Prevention:
      • Override the clone method to prevent the Singleton instance from being cloned.
                @Override
                protected Object clone() throws CloneNotSupportedException {
                  throw new CloneNotSupportedException("Cannot clone a Singleton object");
                }
              
    • Enum Singleton:
      • Using an enum in Java is a simple way to implement a Singleton, as enums are inherently thread-safe and prevent serialization issues.
                public enum Singleton {
                  INSTANCE;
                }
              

Example Overview
public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // Private constructor
    }

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

Key Principles
  1. Single Instance: Ensure only one instance of the class exists.
  2. Controlled Access: Provide a single access point to the instance.
  3. Prevent Instantiation: Prevent external instantiation via private constructors.
  4. Thread Safety: Ensure thread safety when multiple threads might access the instance.
These elements ensure the Singleton Pattern fulfills its purpose efficiently and reliably.

Motivation for the Singleton

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 one 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 involves only one class which is required to instantiate itself and to make sure it creates not more than one instance.
At the same time it provides a global point of access to that instance. In this case the same instance can be accessed from anywhere, making it impossible to directly invoke the constructor each time.
  • Intent
    1. Ensure that only one instance of a class is created.
    2. Provide a global point of access to the object.
  • Implementation The implementation involves
    1. a static member in the "Singleton" class,
    2. a private constructor and
    3. a static public method that returns a reference to the static member.


UML Class Diagram for the Singleton Pattern
The graphic is a UML Class Diagram that represents the implementation of the Singleton Design Pattern. Here's a detailed description of its elements:
Class Name Singleton: The diagram contains a single class named `Singleton`, which is the implementation of the Singleton pattern.
Attributes
  1. - instance: Singleton:
    • This is a private static attribute (- indicates private visibility) of type Singleton.
    • It holds the single instance of the class.
    • This attribute ensures that only one instance of the class is created and shared throughout the application.

Operations/Methods
  1. - Singleton():
    • This is the private constructor (- indicates private visibility).
    • It ensures that the class cannot be instantiated from outside, restricting object creation to within the class itself.
  2. + getInstance(): Singleton:
    • This is a public static method (+ indicates public visibility).
    • It provides a global access point to the instance attribute.
    • The method returns the single instance of the class, creating it if it does not already exist.

Relationships The arrow looping back to the class indicates that the `getInstance()` method is responsible for returning the existing `Singleton` instance or creating it if it doesn't exist.
Summary This diagram depicts the essential components of the Singleton pattern:
  1. A private static instance variable (instance).
  2. A private constructor to prevent direct instantiation.
  3. A public static getInstance() method for controlled access to the single instance.
This is the typical structure of a class implementing the Singleton Design Pattern. Let me know if you'd like further elaboration or code examples!

The Singleton Pattern defines a getInstance operation which exposes the unique instance which is accessed by the clients.
getInstance() is is responsible for creating its class unique instance in case it is not created yet and to return that instance.
The upcoming modules introduce you to many more patterns.
In the next module, you will have a chance to work with another creational pattern, the "factory method" pattern.

SEMrush Software