[UPDATE : This post is outdated. Check out the new post on singletons.]

Singleton is one of the most common and easiest design pattern. In fact, a lot of designs are wrong just because the developer didn't know about singletons and design patterns (I could have said : a lot of my designs were wrong just because I didn't know about singletons and design patterns).

I was looking at the first three results for singleton javascript on Google and I was more than deceived by what they had to tell us. That's why I write this article.

What is a singleton class?

A singleton is when your application needs to use just one instance of an object to centralize your access to it. Example, I have a list of cat names that can be used in various functions of an application. Sometimes, names are added or removed. I could use a global variable to the page containing the list. The problems are :

  • It's a global variable (global variables are bad).
  • I don't know when the list is created or initialized.
  • If you reuse your class in another project, you will always need to define a global variable and instance it correctly.
  • It's ugly.

If I use a singleton pattern, the advantages are :

  • The object is always correctly created.
  • You don't have to ask yourself questions about the state of the list or whatever. It just works!
  • Another programmer can recognize the singleton pattern thus making it easier for him to work.

    How to write a singleton class

    Before writing a singleton, you need to know about creating objects and static functions.
// I create the class
  function CatNames() {
      this.names = new Array(); // The array that will contain the names
  }
  
  CatNames.instance = null; // Will contain the one and only instance of the class
  
  // This function ensures that I always use the same instance of the object
  CatNames.getInstance = function() {
      if (CatNames.instance == null) {
          CatNames.instance = new CatNames();
      }
  
      return CatNames.instance;
  }
  
  // Function to add a cat name
  CatNames.prototype.add = function(catName) {
      this.names.push(catName);
  }
  
  // Function to remove the last cat name
  CatNames.prototype.removeLast = function() {
      return this.names.pop();
  }
  
  // Function to alert all cat names
  CatNames.prototype.alertAllCats = function() {
      alert(this.names.join(","));
  }

I use it in these functions.

function addThreeNames() {
      // I use the one and only instance of the class (the magic of singletons)
      var names = CatNames.getInstance();
  
      names.add("Mistigri");
      names.add("Bibi");
      names.add("Gary");
  }
  
  function removeLastCat() {
      // Once again, singleton is here
      var names = CatNames.getInstance();
  
      names.removeLast();
  }
  
  // I call the functions
  // - no need for a global variable
  // - no need to create the object and pass it as parameter
  addThreeNames();
  removeLastCat();
  
  // Alert all cats
  var names = CatNames.getInstance();
  names.alertAllCats();

The downside of this technique

Yes I know, you can instantiate the singleton class if you want.

var catNames = new CatNames();

You know what? You'll have to follow a simple rule : never instantiate a singleton class. Maybe we could use more techniques that would protect you from instantiating your own singleton class but it would be a waste of time and code.

comments powered by Disqus