Singleton Pattern
This lesson discusses the singleton pattern in detail using a coding example.
We'll cover the following
What is the singleton pattern?
The singleton pattern is a type of creational pattern that restricts the instantiation of a class to a single object. This allows the class to create an instance of the class the first time it is instantiated; however, on the next try, the existing instance of the class is returned. No new instance is created.
Example #
A real-life example is that of a printer which the office employees want to use. It’ll be a shared resource amongst all the employees. Hence, a single instance of the printer is required that everyone can share instead of having a new instance for each employee who wants to print something.
Let’s see how we can implement the singleton pattern for the printer:
let instance = null;class Printer {constructor(pages) {this.display= function(){console.log(`You are connected to the printer. You want to print ${pages} pages.`)}}static getInstance(numOfpages){if(!instance){instance = new Printer(numOfpages);}return instance;}}var obj1 = Printer.getInstance(2)console.log(obj1)obj1.display()var obj2 = Printer.getInstance(3)console.log(obj2)obj2.display()console.log(obj2 == obj1)
Explanation
In the example above, we are implementing the singleton pattern. The class Printer
can only have a single instance. We ensure this in the getInstance
function. Let’s look at it in detail.
getInstance
function accepts the parameter numOfpages
. Inside the function, on line 10, we check if an instance
for the Printer
class already exists.
if(!instance) //line 10
If it does not exist, the code inside the if
condition executes and a new instance is created.
instance = new Printer(numOfpages)
However, if an instance
already exists, it simply returns the existing instance instead of creating a new one.
return instance
You can see this in the output as well. We create an instance of the Printer
with 2
passed as the argument to getInstance
:
var obj1 = Printer.getInstance(2)
console.log(obj1) //line 18
obj1.display() //line 19
For lines 18 & 19, you see the following output on the console:
"Printer { display: [Function] }"
"You are connected to the printer. You want to print 2 pages."
Next, we try to create a second instance of the Printer
with 3
passed as the argument to getInstance
.
var obj2 = Printer.getInstance(3)
console.log(obj2) //line 21
obj2.display() //line 22
You see the following output for the commands on lines 21 & 22:
"Printer { display: [Function] }"
"You are connected to the printer. You want to print 2 pages."
As you can see, instead of a new instance, the same instance is returned. Hence, obj2.display
shows 2 pages
instead of 3 pages
. Line 23 also returns true
, showing that both the instances are the same.
console.log(obj2 == obj1) //line 23
When to use the singleton pattern? #
The singleton pattern is mostly used in cases where you want a single object to coordinate actions across a system. Singletons are mostly used by:
-
Services: services can be singleton since they store the state, configuration and provide access to resources; hence, it makes sense to have a single instance of a service in an application.
-
Databases: when it comes to database connections, databases such as MongoDB utilize the singleton pattern.
-
Configurations: if there is an object with a specific configuration, you don’t need a new instance every time that configuration object is needed.
Now that you know what the singleton pattern is, it’s time to implement it!