A singleton is an object which only exists in one copy. Attempting to create an instance will return that single existing one. Services in Angular are a good example of singletons. But we’re not talking about Angular here. When do you need a singleton? The answer: when you have a single general purpose service for your entire app. You usually need a singleton if your service needs to retain its state throughout various places in your app. The essence of singletons Here’s a very brief example. export class Logger { private static instance: Logger; constructor() { Now you can use this singleton in your code: import { Logger } from './services/logger'; That’s it. Let’s see a practical example! The example above makes little practical sense, as we could use 2020-11-03 So let’s modify our service to do all this. Let’s start with displaying the time for every log line. log(message) { I’m simplifying the example here and there. The timestamp will not be padded, so you will end up seeing 3:22:1 instead of 03:22:01. I’ll leave that to you to implement. So now we have timestamps, but we’d like to display the date whenever a new day begins. Let’s add a private variable to our module called lastLogDay. It will store — you guessed it — the last day when a line was displayed. private lastLogDay = 0;log(message) { Now before every log output the method checks if the current date is different from the last saved one, and displays the full date if it is. Then after the log output it saves the current date to lastLogDay. This is why we needed a singleton! If we created a new instance of Logger every time we needed it, all the instances would work, but they’d randomly display the date here and there, whenever either of them notices that the date is different from when they were last called. By having a singleton we have only one Logger, and one lastLogDay. One of the most popular creational design pattern is the Singleton, which restricts instantiation of a class to a single object only. In this post post, I will show you how to implement the above-mentioned pattern using TypeScript. TypeScript key features The bible of the design patterns, namely the book by Gang of Four (GoF), contains code examples in the statically typed C++ language. However, TypeScript allows to implement the Singleton pattern thanks to the following features:
The Singleton pattern Let’s consider the ActionsBus class which is supposed to be instantiated only once, since there should be a single point to dispatch an action. In addition, it should be possible to become notified about each event in the system by simply subscribing in one place: The key points are:
Note that within the getInstance method you can reference the class using the this keyword as well: The Singleton in action Let’s verify that there’s only a single instance of the ActionsBus class in the system: First, notice that it’s illegal to instantiate the class directly due to the private access modifier of its constructor. The existence of a single instance has been proved by comparing references to object returned from the invocations of the getInstance static method. In addition, if you subscribe to the action$ observable with the aid of the former reference, you will be notified about the action dispatched using the latter: Conclusions The Singleton pattern is one of the easiest to understand, therefore it’s a good starting point to get familiar with the topic. TypeScript (a superset of JavaScript) has all the features required to make use of the design patterns covered in the GoF’s book. |