The Singleton design pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. It’s commonly used in scenarios where exactly one instance of a class is needed to control access to a shared resource, manage configuration settings, or coordinate actions across the application.
In JavaScript, implementing the Singleton pattern can be achieved using various techniques, such as object literals, closures, or ES6 classes. Here’s an example of how you can implement a Singleton using a JavaScript class:
class Singleton {
constructor() {
if (!Singleton.instance) {
// Create the singleton instance if it doesn't exist
Singleton.instance = this;
}
// Return the existing instance if it already exists
return Singleton.instance;
}
// Additional methods and properties can be added here
}
// Usage
const singleton1 = new Singleton();
const singleton2 = new Singleton();
console.log(singleton1 === singleton2); // Output: true
In this example:
- The
Singleton
class has a private static property namedinstance
, which holds the singleton instance. - The constructor of the
Singleton
class checks whether theinstance
property already exists. If it doesn’t, it creates a new instance and assigns it to theinstance
property. If it does, it returns the existing instance. - By ensuring that the constructor always returns the same instance, the Singleton pattern guarantees that there is only one instance of the class throughout the application.
It’s important to note that while the Singleton pattern provides a global point of access to the instance, it also introduces global state, which can make the code harder to test and maintain. Therefore, it should be used judiciously and only in scenarios where a single instance is truly necessary. Additionally, in multi-threaded environments, special care must be taken to ensure thread safety when implementing the Singleton pattern.
5 Examples of Singleton Design Pattern
Using an Object Literal
const singleton = {
instance: null,
getInstance() {
if (!this.instance) {
this.instance = { /* Singleton instance properties */ };
}
return this.instance;
}
};
// Usage
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // Output: true
Using a Closure
const singleton = (function() {
let instance;
function createInstance() {
return { /* Singleton instance properties */ };
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// Usage
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // Output: true
Using ES6 Class
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
}
// Usage
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // Output: true
Using ES6 Class with Static Method
class Singleton {
static instance;
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
// Usage
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // Output: true
Using a Proxy
const singleton = new Proxy({}, {
instance: null,
get(target, prop) {
if (!this.instance) {
this.instance = { /* Singleton instance properties */ };
}
return this.instance[prop];
}
});
// Usage
const instance1 = singleton;
const instance2 = singleton;
console.log(instance1 === instance2); // Output: true
These examples demonstrate different approaches to implementing the Singleton pattern in JavaScript, each with its own advantages and use cases. Depending on the requirements and preferences of your project, you can choose the implementation that best suits your needs.
Singleton Design Pattern When’s
let’s have a look at few example following product, services, situations, user behaviour and more to better understand when we’ll be using Singleton Design Pattern. Some might sound familiar some not, but repeating those will “click in” what’s a singleton is.
User Authentication System
Product Example: A web application that requires users to log in before accessing certain features.
Singleton Usage: Implementing a Singleton pattern for the user authentication service ensures that there is only one instance of the authentication service throughout the application. This allows for centralized management of user authentication status and credentials.
Theme Manager in a UI Library
Product Example: A UI library for building web applications that offers various themes (e.g., light mode, dark mode).
Singleton Usage: Using a Singleton pattern for the theme manager ensures that there is a single instance responsible for managing the current theme across the entire application. This enables consistent theming throughout the UI components and simplifies the process of switching between different themes.
Shopping Cart in an E-commerce Platform
Product Example: An online marketplace where users can add items to their shopping cart and proceed to checkout.
Singleton Usage: Employing a Singleton pattern for the shopping cart ensures that there is only one instance of the cart object across the application. This allows for seamless management of the user’s shopping session and prevents multiple instances of the cart from conflicting with each other.
Notification Center in a Mobile App
Product Example: A mobile application that delivers push notifications to users for various events or updates.
Singleton Usage: Implementing a Singleton pattern for the notification center ensures that there is a single instance responsible for handling incoming notifications and displaying them to the user. This centralizes the management of notifications and ensures that users receive consistent and timely alerts.
User Preferences Manager in a Settings Menu
Product Example: A settings menu within an application where users can customize their preferences (e.g., language, notification preferences).
Singleton Usage: Using a Singleton pattern for the user preferences manager ensures that there is only one instance responsible for managing the user’s settings across the application. This simplifies the implementation of features that rely on user preferences and ensures that changes made to preferences are reflected consistently throughout the application’s UI.
Lior Amsalem embarked on his software engineering journey in the early 2000s, Diving into Pascal with a keen interest in creating, developing, and working on new technologies. Transitioning from his early teenage years as a freelancer, Lior dedicated countless hours to expanding his knowledge within the software engineering domain. He immersed himself in learning new development languages and technologies such as JavaScript, React, backend, frontend, devops, nextjs, nodejs, mongodb, mysql and all together end to end development, while also gaining insights into business development and idea implementation.
Through his blog, Lior aims to share his interests and entrepreneurial journey, driven by a desire for independence and freedom from traditional 9-5 work constraints.
Leave a Reply