Singleton
The Singleton design pattern is a popular design pattern that provides global access to an instance of a class.
Motivation
Sometimes in the program, we need to share a single instance within multiple blocks or objects without having to pass it in the constructor every time. A perfect example is a database connection instance, the whole program works with this one connection and it would be impractical to pass it over and over again everywhere. Making the class providing the database API static could be an easy solution. However, sometimes we might prefer this class to be instantiable (for example, we sometimes work with multiple connections), or we use an already existing class which is not static. So, we'll wrap it by a Singleton.
Pattern
The pattern consists of a class which ensures that only one instance of it can exist.
First of all, we must prohibit the user from creating an instance, so we implement an empty private constructor.
Next, we create a common instance variable and put the instance which we want to share in the program into it. In our case, this is a database connection instance.
Now, the class creates an instance of itself and stores it into a static variable. This is how the class manages its instance and the user can only access it through this class as they cannot create it on their own. So we have it completely under control. Of course, we set the instance as private and also as read-only.
Finally, we create a public method through which we'll access the instance from the outside. Inside the method, we return the instance.
Sample Source Code (C#)
class Singleton { private Singleton() { } public Database database = new Database('host', 'name', 'password'); private static readonly Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } }
Usage in the program
We then access the connection as follows:
Connection connection = Singleton.getInstance();
As the word singleton means the only child, here it refers to an instance having no other siblings.
Possible modifications
The getInstance()
method allows us to initialize the instance
not before we need it. So we can modify the code as follows:
class Singleton { private Singleton() { } public Database database = new Database('host', 'name', 'password'); private static Singleton instance = null; public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
Sometimes, this is the way to optimize the program performance. This version isn't thread-safe, and if we worked with multiple threads, it'd be necessary to put the instance initialization into a lock.
Disadvantages
The word global can always be a bit controversial, and therefore, Singleton is sometimes considered as an anti-pattern. Although every programmer should know the Singleton pattern, it's not the ideal pattern for passing dependencies in the application. Dependency Injection is a better way how to manage dependencies. If you are interested in this topic, we recommend our Software Architecture and Dependency Injection course. A thread-safe Singleton is a reasonable usage of the pattern in multithreaded applications.