The Singleton Pattern

The Singleton Pattern provides only one instance of a class. It is useful when we want to centralize a certain behavior such as querying the database or writing in files.

First, we want to make sure we create only one instance. The basic pattern looks this way:

public class Singleton {

  private static final Singleton INSTANCE = new Singleton();

  private Singleton() {} // not possible to call the constructor from outside the class

  public static Singleton getInstance() {
    return INSTANCE;
  }
}

There are problems with this though. It is possible to create more than one instance by using:

  1. the Reflection API
  2. Serialization. The JVM does not care about the private constructor when serializing/deserializing. To fix this, we just need to add the readResolve method:
protected Object readResolve() {
  return INSTANCE; // return the existing instance instead of creating a new one.
}

For Serializable classes, the readResolve method let us replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized.

Second, we want to guarantee a lazy initialization. We want to make sure we only create the instance when we need it. It can be as simple as:

publics static Singleton getInstance() {
  if (instance != null) {
    instance = new Singleton();
  }
  return instance
}

Third, we want to guarantee thread safety. In the previous case, if there are multi-threads and they access the method at the same time, they may create their two instances (one for each thread). It is possible to create an inner static Singleton using a nested class:

class Singleton {

  private Singleton() {}

  // Nested class 
  private static class Builder {

     private static final Singleton INSTANCE = new Singleton();

     public Singleton getInstance() {
       return Builder.INSTANCE;
     }
  }
}

It is also possible to use enum instead of class. Using an Enum solves the issue with the Reflection API, but it does not allow you to persist an internal state through serialization despite the fact that all the enum are serializable. For example:

public enum Singleton {
  INSTANCE; // name of the enum
  
  Singleton() { // Constructor is always private
    // constructor if needed
    myState = "VALUE"; 
  }

  private String myState;
  public void setValue(String myState) {
    this.myState = myState;
  }
}

If you set the value of myState before serializing the enum, the deserialization will return to the default value set in the constructor which is here “VALUE.” This is a possible limitation for using enum (as well as the impossibility to create subclasses).

Good tips about using a singleton

  • When to use a singleton? For example, we want to create a class that manages displaying maps. Should I use a singleton or a regular class? It seems it could be a singleton. A few questions can help decide:
    • Does the instance access resources that are shared?
    • Should we limit the creation of this class to only one instance? (What if we want to create another map section?)
    • Is it worth the effort to make it thread safe?
  • How to handle resources in the Singleton? A good idea is to use the principle of dependency injection to be able to test the Singleton as well as making sure it is adaptable. Let’s illustrate it quickly with a singleton managing database connections:
enum dbConnector {
  INSTANCE;
  ... // constructor

  public Connection getConnection() {
    DB database = new DB("Oracle"); // hardwire dependency
    return database.getConnection();
  }
}

We can inject the dependency to the database:

enum dbConnector {
  INSTANCE;
  ... // constructor

  public Connection getConnection(DatabaseManager dbMgr) {
    DB database = dbMgr.get("Oracle"); // the dependency is injected
    return database.getConnection();
  }
}

Author: Toujon Lyfoung

This paragraph is supposed to be the place where I put my credentials and achievements. In my opinion, degrees and jobs do not tell much about a person. If you want to know me, read my posts! Blogging has been fun. I do not pretend to do much. I am simply processing, tracking and sharing my reflection. Comments are definitely welcomed to help me continue in my learning.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s