Singleton Design Pattern

Imagine one fine Monday morning your project manager comes up to you and informs you that a new requirement has come up in your latest project. The Preference module in your software reads hard coded value but your project manager wants you to modify it so that the values are read from a database.

At once you start to think of how will you solve the problem. Here is a very simplified class diagram of Preferences class with its two callers:

Class diagram: Preferences is called multiple times by RpcCaller and ApiCaller.

Preference class has the values hard coded in there. RpcCaller and ApiCaller creates Preference objects each time they need to make a RPC call or an API call respectively. The Preference objects were quite light weighted so there were not a significant performance issue but now with the new requirement, creating so many objects will degrade the performance significantly.

So what will you do? Can you think of a solution?

I will highly recommend to pause for a minute and think of the what solution will you come up with.

Now lets look at different ways we could solve the problem. Clearly the requirement is:

  1. To create one and only one object of Preference class no matter what.
  2. Multiple classes require the same object instance.

There are two ways you can do it:

  1. Global variables.
    • But the problem with global variables is that it won’t restrict other classes to create another object.
    • So our requirement of one and only one could not be enforced using global variables.
  2. Singleton class.
    • A singleton class is one that has one object throughout the lifetime of the application.
    • It fits perfectly with our use case, so let’s explore what are singleton classes.

Singleton design pattern

The intent of this design pattern is to create a class which has one instance and provide a single point of access to that instance.

When should we use this design pattern?

  1. When only one instance of the class is required.
  2. There could only be one access point.
  3. and we need to manage the object instances.

So far so good but how does a singleton class should look like. I will be using C++ to demonstrate a very basic skeleton.

class Singleton
{
    public:
        static Singleton& GetInstance() {
            // Guaranteed to be destroyed and Instantiated on first use.
            static Singleton instance;
            return instance;
        }
    private:
        // Private Constructor.
        Singleton() {}                   

    public:
        // Don't allow assignment.
        Singleton(Singleton const&) = delete;
        void operator=(Singleton const&) = delete;
};

Let me explain what is going on.

First, we make the constructor private and disallow any assignment operations. So nobody else can create a copy of it. The only way to get the instance of the class is to call the GetInstancemethod and in the GetInstance method the one instance of the class has been created as a static variable. As per the C++ standard:

Dynamic initialization of a block-scope variable with static storage duration (6.6.4.1) or thread storage duration (6.6.4.2) is performed the first time control passes through its declaration; such a variable isconsidered initialized upon the completion of its initialization

and

Destructors (15.4) for initialized objects (that is, objects whose lifetime (6.6.3) has begun) with static storage duration, and functions registered with std::atexit, are called as part of a call to std::exit(21.5). The call t ostd::exit is sequenced before the invocations of the destructors and the registered functions. [Note:Returning from main invokes std::exit(6.8.3.1).— end note]

So the static variable will be initialized the first time somebody calls the GetInstance and will be safely destroyed at the end. Furthermore, it is thread safe. Why? From the same C++ standard:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

So the static variable will be initialized only once in the thread that reaches that the statement first.

Phew! That was lot to digest but hopefully this article helped you understand the Singleton design pattern.

Exercise

  1. In the simple example above the constructor was pretty simple. What would you do if the constructor in your code requires some work to do like accessing a database or authenticating the user session?
  2. How will you solve the initial problem of modifying Preference module to be allowed to call once and only once?

Please let me know your answers in the comments below. Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.