Contents

3 Ways to Implement the Singleton Pattern in TypeScript With Node.js

3 Ways to Implement the Singleton Pattern in TypeScript With Node.js

Choose which way works best for your needs.

https://cdn-images-1.medium.com/max/800/1*XWTl47NNOuj2nDIFKYe-TA.jpeg

Source: Unsplash

The singleton pattern is one of the most straightforward creational design patterns to implement. Aside from being easy to understand, it doesn’t require that many lines of code to write.

Throughout my career, I’ve come across code that uses different singleton implementation variations. I thought it would be great to compile these types of implementations in one article so that readers can use it as a reference in their future projects.


Singleton Review

Let’s start with a quick review of what problem a singleton pattern is trying to solve. A singleton pattern is used to maintain asingleinstance of an object without creating a new one — even if the instance is used in different parts of our application.

https://cdn-images-1.medium.com/max/800/1*-DMrn3qEm3_50IeVkXlT2A.png Singleton high-level diagram by the author.

This approach applies to object instantiations that you do not want to repeat. Some examples of implementations are logging, caching, and database connection.

We will use logging as an example in this article.


The Problem — Logging Example

Here’s an example problem: I have a Node.js app for payment processing that uses aLoggerclass. We want to keep a single logger instance in this example and ensure theLoggerstate is shared across the Payment app. To keep things simple, let’s say that we need to ensure that the logger needs to keep track of the total number of logged messages within the app. Ensuring that the counter is tracked globally within the app means that we will need a singleton class to achieve this.

https://cdn-images-1.medium.com/max/800/1*7RGSs1aUf-0yMYzSymSG_w.png A high-level diagram of the sample app by the author.

Let’s go through each of the classes that we will be using.

Logger class: Logger.ts

A basic logger class that allows its clients to log a message with a timestamp. It also allows the client to retrieve the total number of logged messages.

View Code on GitHub Gist

Payment class: Payment.ts

ThePaymentprocessing class processes the payment. It logs the payment instantiation and payment processing:

View Code on GitHub Gist

The entry point of the app: index.ts

The entry point creates an instance of theLoggerclass and processes the payment. It also processes the payment through thePaymentclass:

View Code on GitHub Gist

If we run the code above, we will get the following output:

# Run the app
tsc && node dist/creational/singleton/problem/index.js

https://cdn-images-1.medium.com/max/800/1*M5fCdVwhXr-xdDQRNkN1Ig.png Output screenshot by the author.

Notice that the log count stays at1despite showing3logged messages. The count remains at1because a new instance ofLoggeris created inindex.tsandPayment.tsseparately. The log count here only represents what’s logged inindex.ts. However, we also want to include the number of logged messages in thePaymentclass.

Here are different ways to solve this problem by using a singleton design pattern.


GitHub Repository (Optional)

If you want to follow along with the TyepScript code examples below, the code I’m using is available in the following GitHub repository:

Clone a local copy or run it directly in Gitpod.


Solution #1: Add a Separate Singleton Class

We can add aSingletonclass to the`