DEV Community

Cover image for Design Patterns: Singleton Pattern
Islam Elgohary
Islam Elgohary

Posted on • Originally published at ielgohary.github.io

Design Patterns: Singleton Pattern

Continuing my Intro to Design Patterns series; today I will explain the singleton design pattern.

You know how you can have one global variable in your application? Singleton pattern is the same but for classes.

The Singleton design pattern is a creational pattern and it's a very simple one actually. Basically, if you need only one instance of a class in your application then that's when you use a singleton pattern. The singleton pattern is a class that can have only one instance in the application.

Problem

I will use a simple example here of a counter. Let's assume that you have a chat room and you want to keep count of how many people are currently online without using a database. For the sake of simplicity let's assume that we don't need that information to be persistent so we are ok with the counters resetting when the application restarts. In this case we can just use a class with a variable that keeps track of users count. the class can look like this:

class UserCount {
  private counter int;

  constructor UserCount(){
    this.counter = 0;
  }

  function Increment() {
    this.counter++;
  }

  function Decrement() {
    this.counter--;
  }
}

class Auth {
  counterInstance UserCount;

  constructor Auth() {
    this.counterInstance = new UserCount();
  }

  function Login(request){
    // Check username and password then log the user in
    this.counterInstance.Increment()
  }

  function Logout(request){
    // Logout the user
    this.counterInstance.Decrement()
  }
}

Enter fullscreen mode Exit fullscreen mode

With that implementation, we have a class that has one variable that is initialized to be zero. it can then be incremented and decremented.
Class Auth uses this class and whenever a user logs in, the number is incremented, whenever they logout it's decremented.

This works fine for our case since users are counted only when they login and we only have one class that uses the UserCounter class. But now we allow users to add a guest to the chat where guests can chat without being logged in.

We now have a new class GuestChat that will need to use the UserCounter class. If we use the same implementation of UserCounter each class will have its own independent counter because it will have its own instance of the UserCounter class.

class GuestChat {
  counterInstance UserCount;

  constructor GuestChat() {
    this.counterInstance = new UserCount();
  }

  function AddGuest() {
    // Create a new guest
    this.counterInstance.Increment();
  }

  function RemoveGuest() {
    // Remove a guest
    this.counterInstance.Decrement();
  }
}
Enter fullscreen mode Exit fullscreen mode

Solution

Here comes the singleton pattern. Instead of having multiple instance of UserCounter, we can implement the class in a away that creates only one instance and whenever an instance exists, all classes will use it. The implementation would look like this:

class UserCount {
  private static instance UserCount;
  private counter int;

  static function GetInstance() {
    if (this.UserCount == null) {
      this.instance = new this.UserCount();
      return this.instance;
    } else {
      return this.instance;
    }
  }

  private constructor UserCount(){
    this.counter = 0;
  }

  function Increment() {
    this.counter++;
  }

  function Decrement() {
    this.counter--;
  }
}
Enter fullscreen mode Exit fullscreen mode

Here are the changes that we applied to UserCount class:

  1. Create a new private variable instance and make it static. static variables and static functions are associated with the class itself and not with the object. So whenever the class is called it will reference the same static variable/function.
  2. Make the constructor private. This way other classes cannot create new instances of the class and it's completely up to the class itself to decide when to create a new instance.
  3. Create a new function GetInstance which returns the instance if it has already been created or create a new instance (using the private constructor) if it does not exist.

Now classes Auth and GuestChat will be changed to the following:

class Auth {
  counterInstance UserCount;

  constructor Auth() {
    this.counterInstance = UserCount.GetInstance();
  }

  function Login(request){
    // Check username and password then log the user in
    this.counterInstance.Increment()
  }

  function Logout(request){
    // Logout the user
    this.counterInstance.Decrement()
  }
}


class GuestChat {
  counterInstance UserCount;

  constructor GuestChat() {
    this.counterInstance = UserCount.GetInstance();
  }

  function AddGuest() {
    // Create a new guest
    this.counterInstance.Increment();
  }

  function RemoveGuest() {
    // Remove a guest
    this.counterInstance.Decrement();
  }
}
Enter fullscreen mode Exit fullscreen mode

In the constructor, instead of creating a new instance of UserCount, both classes call GetInstance() instead. This means that only one class will create a new instance and then that instance will be shared with both classes.

Conclusion

The singleton design pattern uses access modifiers to limit creation of instances of the class allowing for having a global instance of the class throughout the whole application where other classes can only get the instance but they cannot directly create new instances at will. The example I used is very simple but this is usually used for resources like database connections because you usually need to create the connection once and then use it everywhere instead of creating a new connection each time you want to connect to the database.

Photo by Markus Spiske on Unsplash

Top comments (0)