Singleton Pattern in TypeScript — ✨ Creational Design Pattern #5

365kim
3 min readMay 13, 2023

--

Photo by Marcel Eberle on Unsplash

🙋🏻‍♀️ What is the Singleton Pattern?

The Singleton Pattern is a design approach that limits the creation of a class to only one instance which is accessible from all parts of the code globally.

The term singleton comes from the mathematical concept of a singleton set which is a set that contains exactly one element. In programming, the Singleton Pattern is a way of implementing this concept for classes.

How is it different from using Global Variables?

Using Singleton Pattern might sound like using global variables, but they are different! The Singleton Pattern can provide a more encapsulated way to manage shared data, compared to using global variables.

Global variables are typically defined and initialized outside of a class, while the Singleton Pattern is implemented as a class (with a private constructor and a static method) to retrieve the single instance of the class.

Moreover, in the case of a global variable, any part of the program can access and modify its value, which can lead to data inconsistency and make it difficult to debug. On the other hand, the Singleton Pattern ensures that there is only one instance of a class, and provides a controlled way to access and modify the state of that instance, ensuring that the state of the program is consistent across all parts of the code.

✨ Simple TypeScript Example

In TypeScript, how can you ensure that only a single instance is created within a class? This can be achieved by excluding a public constructor. and including a private constructor and a static method called getInstance().

class Store {
private static instance: Store
private count: number

private constructor() {
this.count = 0
}

static getInstance(): Store {
if (!Store.instance) {
Store.instance = new Store()
}
return Store.instance
}

readStore(): void {
console.log(`Count: ${this.count}`)
}

getCount(): number {
return this.count
}

setCount(value: number): void {
this.count = value
}
}

The class Store has a private static variable instance which is an instance of the Store class. The constructor method of the Store class is marked private so that it cannot be called from outside the class. This ensures that no other instance of the Store class can be created from outside the class.

The getInstance() method is a static method that is responsible for creating and returning the instance of the Store class. It first checks whether an instance of the class already exists. If an instance does not exist, it creates a new instance of the class and assigns it to the instance variable. If an instance already exists, it simply returns that instance.

Let’s say you call the static method getInstance() in A.ts, the instance of Store class will be created for the first time. (This is called lazy initialization.)

// src/A.ts
const store = Store.getInstance()

store.readStore() // "Count: 0"
store.setCount(365)
store.readStore() // "Count: 365"

Then, if you call getInstance() in B.ts, you will retrieve the only instance you created before, and get the consistent result.

// src/B.ts
const store2 = Store.getInstance()

store.readStore() // "Count: 365"
store2.setCount(0)
store.readStore() // "Count: 0"

You can also try eager initialization if you’re concerned about multithreading issues. Here, the instance variable is initialized with the new keyword when the class is loaded into memory.

class Store {
private static instance = new Store()

...

static getInstance(): Store {
return Store.instance
}

🧑🏻‍💻 Use it or Avoid it

When to use it

The Singleton Pattern is useful when you want to ensure that there is only one☝️️ instance of a particular class in your program. Examples are when you want to save resources, make consistent results, or avoid unexpected behavior in your program due to reading and writing on different instances.

When to avoid it

However, it’s important to be cautious when using the Singleton Pattern, because a singleton class may tightly couple different parts of your code, violating SRP(Single Responsibility Principle). The singleton class can manage its instance, provide global access to that instance, and perform other operations related to its purpose. These multiple responsibilities can make the class more complex, harder to write test codes, and eventually harder to maintain. (So, you may want to separate other operations into different classes.)

In short, Singleton Pattern is a design pattern that ensures that a class has only one instance and provides a global point of access to it.

--

--

365kim
365kim

Written by 365kim

Web Front-End Developer who believes Every Day Counts!

No responses yet