Singleton

The Singleton pattern is perhaps the most overused pattern. It is also a pattern that has fallen out of favor in recent years. To see why people are starting to advise against using Singleton let's take a look at how the pattern works.

Singleton is used when a global variable is desirable, but Singleton provides protection against accidentally creating multiple copies of complex objects. It also allows for the deferral of object instantiation until the first use.

The UML diagram for Singleton looks like the following:

Singleton

It is clearly a very simple pattern. The Singleton acts as a wrapper around an instance of the class and the singleton itself lives as a global variable. When accessing the instance we simply ask the Singleton for the current instance of the wrapped class. If the class does not yet exist within the Singleton it is common to create a new instance at that time.

Implementation

Within our ongoing example in the world of Westeros, we need to find a case where there can only ever be one of something. Unfortunately, it is a land with frequent conflicts and rivalries, and so my first idea of using the king as the Singleton is simply not going to fly. This split also means that we cannot make use of any of the other obvious candidates (capital city, queen, general, and so on). However, in the far north of Westeros there is a giant wall constructed to keep an ancient enemy at bay. There is only one of these walls and it should pose no issue having it in the global scope.

Let's go ahead and create a singleton in JavaScript:

let Westros;
(function (Westeros) {
  var Wall = (function () {
    function Wall() {
      this.height = 0;
      if (Wall._instance)
        return Wall._instance;
      Wall._instance = this;
    }
    Wall.prototype.setHeight = function (height) {
      this.height = height;
    };
    Wall.prototype.getStatus = function () {
      console.log("Wall is " + this.height + " meters tall");
    };
    Wall.getInstance = function () {
      if (!Wall._instance) {
        Wall._instance = new Wall();
      }
      return Wall._instance;
    };
    Wall._instance = null;
    return Wall;
  })();
  Westeros.Wall = Wall;
})(Westeros || (Westeros = {}));

The code creates a lightweight representation of the Wall. The Singleton is demonstrated in the two highlighted sections. In a language like C# or Java we would normally just set the constructor to be private so that it could only be called by the static method getInstance. However, we don't have that ability in JavaScript: constructors cannot be private. Thus we do the best we can and return the current instance from the constructor. This may appear strange but in the way we've constructed our classes the constructor is no different from any other method so it is possible to return something from it.

In the second highlighted section we set a static variable, _instance, to be a new instance of the Wall when one is not already there. If that _instance already exists, we return that. In C# and Java, there would need to be some complicated locking logic in this function to avoid race conditions as two different threads attempted to access the instance at the same time. Fortunately, there is no need to worry about this in JavaScript where the multi-threading story is different.

Disadvantages

Singletons have gained something of a bad reputation in the last few years. They are, in effect, glorified global variables. As we've discussed, global variables are ill conceived and the potential cause of numerous bugs. They are also difficult to test with unit tests as the creation of the instance cannot easily be overridden and any form of parallelism in the test runner can introduce difficult-to-diagnose race conditions. The single largest concern I have with them is that singletons have too much responsibility. They control not just themselves but also their instantiation. This is a clear violation of the single responsibility principle. Almost every problem that can be solved by using a Singleton is better solved using some other mechanism.

JavaScript makes the problem even worse. It isn't possible to create a clean implementation of the Singleton due to the restrictions on the constructor. This, coupled with the general problems around the Singleton, lead me to suggest that the Singleton pattern should be avoided in JavaScript.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset