Singleton pattern generates and returns the same single instance of a class, in any case. No matter how we generate the instance and how many times we generate it, the same single instance will be returned.
NOTES
In this article, we are discussing the implementation of the Singleton Pattern in TypeScript.
See the Singleton in other languages in the “Other Code Implementations” section. Or, use the link below to check the details of the Singleton Pattern-
Implementation
Singleton pattern implementation in TypeScript is very similar to other object-oriented programming languages(like Java). Here are the key points that we need to follow while implementing the Singleton pattern in TypeScript:
- Create a class for the Singleton implementation.
- Declare a “static” property for storing the instance of the same class.
- Make the constructor “private” so that a new class instance can not be created using the “new” keyword.
- Create a “static” function for getting an instance of the class. In the function check if an instance already exists or not. If an instance exists then return that. And if the instance does not exist, then create a new instance, assign it to the instance variable, and then return that.
Here is a simple and basic example of Singleton pattern implementation in TypeScript.
class Singleton {
// Make sure to make the "private" and "static"
private static singletonInstance: Singleton;
// Make sure to make the constructor "private"
private constructor() {
}
// Make sure to make the function "static"
static getInstance(): Singleton {
// Check if an instance already exists
if (!Singleton.singletonInstance) {
// If instance does not exist then create an instance
// and assign that to "singletonInstance"
Singleton.singletonInstance = new Singleton();
}
// Return the "singletonInstance"
return this.singletonInstance;
}
}
// Use the singleton implementatin like below
const mySingletonInstance = Singleton.getInstance();
// New instance can not be created using the "new" keyword
// as the constructor is declared as "private".
// An attempt like below will generate error
// const someSingletonInstance = new Singleton();
Examples
Here are a few examples of the Singleton pattern implementation in TypeScript.
Example #1: Database Connection
Let’s take the example of creating a class for database connection.
Singleton Class
To create the Singleton class follow these points –
- Create a file named “db-conn-singleton.ts”.
- In the file create a class named “DbConnSingleton”.
- In the class declare a property named “singletonInstance” of type “DbConnSingleton”(same as the class). Make sure to make this property “private static”.
- Declare some properties required for storing connection information, like “host”, “port”, “username”, and “password”. These properties are declared as “readonly” here, we are only going to set these in the constructor.
- Create a constructor, and make it “private”. Accept params for the values of “host”, “port”, “username”, and “password”. Set the values in the constructor.
- Declare a function named “getInstance”. Make this “static”, and accept params for “host”, “port”, “username”, and “password”.
- In the “getInstance” function check if an instance is already created, by checking if the value of “singletonInstance” already exists or not. If it does not exist then create a new instance of the “DbConnSingleton” class and assign that to the “singletonInstance” property. At the end return the “singletonInstance”.
- Create some utility functions as per requirement. We have created some dummy functions here – “printConnectionDetails” and “executeQuery”.
// db-conn-singleton.ts
class DbConnSingleton {
// Declare a private static property, required for the Singleton implementation
private static singletonInstance: DbConnSingleton;
// Some properties for storing some information
// These properties can be declared as readonly if needed
private readonly host: string;
private readonly port: number;
private readonly username: string;
private readonly password: string;
/**
* Constructor
*
* Make sure to make it private for the Singleton implementation
*/
private constructor(host: string, port: number, username: string, password: string) {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
}
/**
* Make sure to declare the function as "static" for the Singleton implemenation
*/
static getInstance(host: string, port: number, username: string, password: string): DbConnSingleton {
// Check if instance is already created or not
if (!this.singletonInstance) {
console.log('Creating new db connection instance');
this.singletonInstance = new DbConnSingleton(host, port, username, password);
}
return this.singletonInstance;
}
// Dummy utility function
public printConnectionDetails() {
console.log("host:" + this.host);
console.log("port:" + this.port);
console.log("username:" + this.username);
console.log("password:" + this.password);
}
// Dummy utility function
public executeQuery(query: string) {
console.log("Executing query: " + query);
}
}
export default DbConnSingleton;
Demo
To use the Singleton implementation use the steps below.
- Create a file named “demo.ts”.
- Create an instance by using “DbConnSingleton.getInstance(……….)”. Provide the param values for “host”, “port”, “username”, and “password”.
- Try to create another instance by using the same process, and pass some different param values.
After the creation of the instances, we can see that both instances are the same. Param passed in the second attempt are not affecting, as the previous instance is returned then.
// demo.js
import DbConnSingleton from "./db-conn-singleton";
// Create on instnce
const dbConnOne = DbConnSingleton.getInstance('loclahost', 1234, 'root', 'secret!pass');
// Print details of the first instance
console.log("DB connection details for dbConnOne:");
dbConnOne.printConnectionDetails();
// Attempt to create another instance
const dbConnTwo = DbConnSingleton.getInstance('192.168.55.55', 2222, 'root2', 'secret!pass2');
// Print details
console.log("DB connection details for dbConnTwo:");
dbConnTwo.printConnectionDetails();
// Both will print the same details
// as both are same instance
Output
Above demo code will generate the below output.
Creating new db connection instance
DB connection details for dbConnOne:
host:loclahost
port:1234
username:root
password:secret!pass
DB connection details for dbConnTwo:
host:loclahost
port:1234
username:root
password:secret!pass
Source Code
Use the following link to get the source code:
Example | Source Code Link |
---|---|
Example #1: Database Connection | GitHub |
Other Code Implementations
Use the following links to check Singleton pattern implementation in other programming languages.