[Javascript] Singleton Pattern
Source: https://javascriptpatterns.vercel.app/patterns/design-patterns/singleton-pattern
With the Singleton Pattern, we restrict the instantiation of certain classes to one single instance. This single instance is unmodifiable, and can be accessed globally throughout the application.
Create a Singleton in Javascritp:
Class:
let instance;
// 1. Creating the `Counter` class, which contains a `constructor`, `getInstance`, `getCount`, `increment` and `decrement` method.
// Within the constructor, we check to make sure the class hasn't already been instantiated.
class Counter {
constructor() {
if (instance) {
throw new Error("You can only create one instance!");
}
this.counter = counter;
instance = this;
}
getCount() {
return this.counter;
}
increment() {
return ++this.counter;
}
decrement() {
return --this.counter;
}
}
// 2. Setting a variable equal to the the frozen newly instantiated object, by using the built-in `Object.freeze` method.
// This ensures that the newly created instance is not modifiable.
const singletonCounter = Object.freeze(new Counter());
// 3. Exporting the variable as the `default` value within the file to make it globally accessible.
export default singletonCounter;
2 points:
- If there is an instance already, we want to throw error.
- Use Object.freeze function to make it unmodifiable.
Object:
let counter = 0;
export default Object.freeze({
getCount: () => counter,
increment: () => ++counter,
decrement: () => --counter,
})
Be carefully about using Singelton:
Depedency Hiding: When importing another module, it may not always be obvious that that module is importing a Singleton. This could lead to unexpected value modification within the Singleton, which would be reflected throughout the application.
Let's say Counter is a singelton. module A and B both import counter and call `increment` twice in each modules.
If in Moulde A, we import Module B. Then `increment` will be called 4 times. But in Module A, we only call twice, that might cause confusion when you just looking at Module A code.
Unnecessary: ES2015 Modules are singletons by default. We no longer need to explicitly create singletons to achieve this global, non-modifiable behavior.