Design Pattern: Singleton Pattern

Summary

Pattern NameSingleton Pattern
Pattern TypeCreational Pattern
ScopeObject
TaglineEnsure only one instance of a class
Use casesWhen we want to ensure that only one instance of a class
is created in any case (Like for, Database connection, File handler, etc.)
Related PatternsAbstract Factory
Builder
Facade
Flyweight
Prototype
Difficulty LevelEasy
Implementations

Definition

For some components/objects in the code, we just need one instance. So that we can store that instance globally and use that instance everywhere.

Like, a database connection or a logging handler, does not need a new instance each time we want to use it, the same instance can be used in all places. Singleton pattern comes into play, in that case.

Singleton pattern is used to ensure that only one instance of a class is created in any case, and whenever you want to get an instance of that class, then the same object instance is returned.

Singleton pattern also ensures easy global access to the singleton object. So we can query(ask for an instance) the class from anywhere(in the application) and the class will return back the same single instance.

WARNING

Singleton pattern may make it difficult to write easily testable code, because of the tight coupling of the class object and its methods.

Use Cases

When we want to handle a database connection or a file resource, we don’t need to create a new object each time. As we want the database connection or the file resource to point to the same connection/resource always.

So we can use Singleton in the following use cases:

  • Database connection
  • File resource handler
  • Caching handler
  • Logging resource handler
  • Network socket connection handler

Implementation

Implementation of the Singleton pattern is simple and involves only one class (the Singleton class).

Use the following steps to implement the Singleton pattern.

Step #1: Prevent the creation of new instances manually

The constructor needs to be private so that a new instance of the class can not be created by using new operator.

Step #2: Make sure the instance is accessible from anywhere

Create a static method for getting the instance of that class. This static method will accept the parameters required to create a new instance of the class.

Step #3: Ensure the return of the same instance each time

  • Use a class variable to store instances.
  • If an instance already exists then return that from the static method.
  • If no instance exists- then create a new instance, store the instance in the class variable, and return that instance from the static method.

Examples

Let’s take a look at a few examples where we need to use the Singleton pattern.

Example #1: Database Connection

Let’s take the example of creating a class for database connection.

Singleton Class

This is the class that has the Singleton implementation. Here are a few key points in the implementation:

A static variable is declared named “Instance”, which holds a reference to an object of the type of the same class.
The constructor needs to be private.
A static method is declared named “getInstance()”. If an instance already exists in the dbInstance variable, then return that, else create an instance and return that.
class DbConnectionSingleton
    var static dbInstance: DbConnectionSingleton
    var url: String
    var port: String
    var username: String
    var password: String
    # Make sure to make it private, so that the constructor can be used directly
    private constructor(
        urlParam: String,
        portParam: String,
        usernameParam: String,
        passwordParam: String
    )
       url = urlParam
       port = portParam
       username = usernameParam
       password = passwordParam
    end constructor
    # Make this method static to access it directly
    static method getInstance(
        urlParam: String,
        portParam: String,
        usernameParam: String,
        passwordParam: String
    ): DbConnectionSingleton
        if (dbInstance == null)
            dbInstance = new DbConnectionSingleton(urlParam, portParam, usernameParam, passwordParam)
        end if
        return dbInstance
    end method
   # Utility function for printing connection information
   method printConnectionDetails()
        output "URL:" + url
        output "Port:" + port
        output "User name:" + username
        output "Password:" + password
    end method
    # Utility method for processing query (dummy)
    method executeQuery(String query: String)
        output "Executing query: " + query
    end method
end class

Demo

While using the Singleton class, directly call the getInstance() method as it is static. No matter how many times the getInstance method is called, with different params, it will return the object that was created the first time.

Here we are calling the getInstance 2 times and the second time calls the object is not changed, and it returns the previous object instead.

# Create an instance of the connection
var dbConnection: DbConnectionSingleton = DbConnectionSingleton.getInstance("localhost", "5432", "postgres", "secret*pass")
output "First Connection Details:"
dbConnection.printConnectionDetails()
# Try creating another connection. This will return the previous existing connection
var secondDbConnection: DbConnectionSingleton = DbConnectionSingleton.getInstance("192.168.55.55", "1234", "postgres2", "secret*pass2")
        
output "Second Connection Details:"
secondDbConnection.printConnectionDetails()

Output

Here is the output generated from the code above.

First Connection Details:

URL: localhost
Port: 5432
User name: postgres
Password: secret*pass


Second Connection Details:

URL: localhost
Port: 5432
User name: postgres
Password: secret*pass

Code Implementations

Use the following links to check Singleton pattern implementation in specific programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.