Singleton design pattern

The singleton pattern is one of the first design patterns that is explained in any design patterns book or tutorial.

Nature wise, singleton pattern belongs to the category of creational design patterns. Patterns from this category are:

Firstly, singleton pattern is used when we want to ensure that only one object of the class will be created.

So, in general, one class can be instanced lots of times. Meaning, we can create multiple objects from one class. However, in some cases we need to ensure that multiple objects can not be created.

Secondly, patterns will never provide us with an actual code, only with a concept. Actual codes that we find online can be proposed by developers or anyone else who actually implemented one pattern.

You like reading about design patterns? Well that’s fantastic!

Subscribe to my newsletter and get notifications about new posts (1 email per week max, just to keep you in “the loop”).

The concept

Classes itself can not “deny” creation of objects, so we need to make some implementation to make this happen. The singleton pattern describes a way on how to accomplish this.

This is a general idea when implementing the singleton pattern.

  1. Firstly, we want to make a dedicated class which can produce only one object.
  2. Secondly, we want to make constructor of this class private, so that this class can not be called from the outside.
  3. Thirdly, we want to create any kind of public function for fetching instance of object.
  4. Then, function for object fetching should have logic that would check if the object already exists or not.
  5. Finally, if the object does not exist it would be created (first time creation), but if the object already exists then existing one would be used.

The singleton pattern – PHP implementation

Here is a simple and quick example on how to implement the singleton pattern in PHP. The latest version of this code and other design patterns can be find within design patterns code repository.

<?php

/*
 * We will create a class called "Singleton".
 * In real use case, this class would have different name.
 */
 class Singleton {
    
    /* We define singleton instance object as static, 
     * so it can be accessed without instancing class.
     */
    private static $singletonInstance = null;
    
    /* 
     * In the case of singleton, we want to have constructor private
     * to prevent some other part of the code executing it.
     * 
     * Since singleton class should be instanced only once, we don't want 
     * other parts of the code having possibility to instance it.
     */
    private function __construct()
    {
      /* 
       * Actual logic of the singleton class.
       * i.e. if we have database connection singaleton class, 
       * then the connection logic goes here.
       */
    }
   
    /**
     * Function which checks if the object of this class already exists.
     * If not, then the object is created (first and the only time).
     * If object already exists, new one will not be created.
     * 
     * @return object Sigleton instance object
     */
    public static function getInstance()
    {
      if (self::$singletonInstance == null) {
          echo "New instance of class is created. \n";
        self::$singletonInstance = new Singleton();
      } else {
          echo "Instance already exist, new instance WILL NOT be created. \n";
      }
   
      return self::$singletonInstance;
    }
}

// Then, for example we would use this object several times on different places.

$object1 = Singleton::getInstance();
$object2 = Singleton::getInstance();
$object3 = Singleton::getInstance();
$object4 = Singleton::getInstance();
$object5 = Singleton::getInstance();

When to use singleton pattern?

Lots of online blogs, tutorials and code junkies will state that singleton is just a glorified global variable. This makes no sense and it is just plain wrong.

Singleton classes are not just another way of wrapping global variables. Idea behind singleton is to make expensive part of the logic (i.e. database connection or log system connection) happening only once and then reused.

Of course, this approach can not and will not solve all coding problems. As every pattern, there are cases when singleton should and can be used and when singleton can not and should not be used.

Having that in mind, misusing singleton can and will cause a lots of potential issues.

This is my opinion on how and when singleton should be used:

  • This pattern should be utilized carefully, meaning in minimum amount of cases and only when we are sure what we want to accomplish.
  • For code logic that is “expensive” and that should not logically be instances multiple times. One common example for this one is “database connectivity class” but again, this depends of our use case.

Singleton as anti pattern

“Anti pattern” means that something is coded or used in the way that is commonly known to be bad. 🙂

Meaning, anti pattern represents common use cases that were recognized as bad implementation or potential issues with using some pattern.

Anti pattern considerations for singleton:

  • Unit testing of code with singleton patterns gets very complex.
  • Knowing actual object state within a specific place in a code tends to be very complex, because we can not be sure what else influenced this object.
  • Possible caching challenges. I.e. we are caching something for one process, which is shared among different processes. Meaning, we are possibly breaking state dependencies.

References