Design Patterns Typescript - Singleton
Tags: designpatterns, typescript, javascript, programming
Published: 2023-09-19 00:10:00

Hello folks! How long has it been since I wrote an article?

So I have the idea to create a several articles exploring design patterns using typescript based on GoF.

In this article I will talk about the first Creational Design Pattern, called **Singleton**

The Singleton Pattern ensure that a class has only one instance and provide a global access point for it.

So we have a global access of the Singleton of all entire application. Also, we can protect the instance with encapsulation, avoiding the override of the value.

![Singleton Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft8df5bg9xu334c79d96.png)

So we have an `instance` that is a private attribute. On this class diagram it's represents as `singleObj`.

And we have a private `constructor` and we have the method called `getInstance` to get the instance of the class.

Imagine that we have an access to the some Database, so for each operation in your operation you need open a new connection to your DB. Sooo, it's a bad idea, don't agree?
We will create a lot of connections for each operation and we will overload our database.

In this case we can use the Singleton! So we can create an unique instace for our entire application, that will be initialized and we will get instance of the connectinon only one time. If the instace is not created we create a new instance, if the same instance is already created we will just use the method `getInstance`.

Let's create a example, for this I will create a `index.ts` with the Singleton Example:

```ts
export class MyDatabase {
  private static instance: MyDatabase;

  private constructor() {}

  static getInstance(): MyDatabase {
    if (MyDatabase.instance === undefined) {
      MyDatabase.instance = new MyDatabase();
    }

    return MyDatabase.instance;
  }
}
```

Notice that we have the `instance` and the `contructor` are privates and to get the instance, we need to call the `getInstance()` of our database.

Now let's add some fake data on memory of users in our Singleton class:

```ts
export interface User {
  id: number;
  name: string;
}

export class MyDatabase {
  private static instance: MyDatabase;
  private users: User[] = [];

  private constructor() {}

  static getInstance(): MyDatabase {
    if (MyDatabase.instance === undefined) {
      MyDatabase.instance = new MyDatabase();
    }

    return MyDatabase.instance;
  }

  addUser(user: User) {
    this.users = [...this.users, user];
  }

  displayUsers(): void {
    console.log(this.users);
  }
}
```

Now we have users, and we can add and display the users in our singleton class.

Before, let's see if the instance created is the same. For that, I will create another file called `useSingleton.ts`:

```ts
import { MyDatabase } from ".";

const myDb = MyDatabase.getInstance();
const myDb2 = MyDatabase.getInstance();

console.log(myDb === myDb2);
```

The output will be:

```bash
true
```

Because, we created the instance of MyDatabase on the first variable `myDb` and the `myDb2` will use the same instace created.

And to use the methods of the singleton class just use:

```ts
import { MyDatabase } from ".";

const myDb = MyDatabase.getInstance();

myDb.addUser({ id: 1, name: "kevin" });
myDb.addUser({ id: 2, name: "uehara" });

myDb.displayUsers();
```

The output will be:

```bash
[ { id: 1, name: 'kevin' }, { id: 2, name: 'uehara' } ]
```

## Trade-offs

Good:
- Access controlled thanks to encapsulation by unique instance
- Use `lazy instanciation`, so the singletion is created only the use moment
- Allow to use on entire project and avoid multiple instantiations.

Bad:
- Sometimes is hard to test
- Violates the Principe of Single Responsability of Solid
- Requires special treatment in cases of concurrency

So that's it people! I hope that this simple article may help help you to understand the Singleton Design pattern.

Thank you so much, to read until here!

Contacts:
Email: uehara.kevin@gmail.com
Linkedin: https://www.linkedin.com/in/kevin-uehara
Youtube: https://www.youtube.com/@ueharakevin/
Instagram: https://www.instagram.com/uehara_kevin/
Twitter: https://twitter.com/ueharaDev
Github: https://github.com/kevinuehara
dev.to: https://dev.to/kevin-uehara