Singleton is a creational design pattern that let you ensure that a class has only one instance and provide a global access point to this instance.
Singleton solves two problems at the time (violating Single Responsibility Principle):
Ensures that class has only a single instance. The most common reason for this is to control some shared resource, for example, database.
Imagine that you had created an object, and after a while, tried to create a new one. In this case, you'd want to receive the old object, instead of creating a new instance.
It can't be done with a regular constructor since every constructor call always returns a new object by design.
Provides global access point to this instance. Sound like a global variable, right? But you can't make a read-only global variable. Anyone who can access it can also replace its value.
There's another side of this problem: code that ensures single instance, scattered all over your program.
Note that Singleton solves both of these problems at the same time. But nowadays pattern became so popular that people call something a Singleton even if it solves just one of these problems.
All singleton implementations share two common steps:
- Making the default constructor private.
- Creating a static creational method that will act as a constructor. This method creates an object using the private constructor and saves it in static variable or field. All following calls to this method return the cached object.
Singleton keeps the single instance production code in one place—inside the creational method of a Singleton class. Any client code that has access to Singleton class gets the access to its creational method as well. And that gives us a global access point to the Singleton instance.
The government is an excellent example of Singleton pattern. A country can have only one official government. Regardless of the personal identities of the individuals who form governments, the title, "The Government of X" is a global point of access that identifies the group of people in charge.
Singleton defines static method
getInstance()that should return the same instance of Singleton class.
Singleton's constructor should be hidden from client code.
getInstance()should be the only way to create and get Singleton objects.
In this example, the database connection class acts as a Singleton. This class does not have a public constructor, so the only way to get its object is to call the
getInstance method. This method caches the first created object and returns it as a result of all subsequent calls.
The Single design pattern guarantees that the only one instance of its class will be created. And it provides a global access point to this instance: the static
class Database is private field instance: Database static method getInstance() is if (this.instance == null) then acquireThreadLock() and then if (this.instance == null) then this.instance = new Database() return this.instance private method Database() is // Some initialization code, such as the actual connection to a // database server. // ... public method query(sql) is // All database queries of an app will go through this methods. // Therefore, you can place here a throttling or caching logic. // ... class Application is method main() is Database foo = Database.getInstance() foo.query("SELECT ...") // ... Database bar = Database.getInstance() bar.query("SELECT ...") // bar would contain the same object as foo.
When program should have a single instance of a class, available to all clients. For example, a single database object, shared by different parts of the program.
Singleton hides from clients all means of creating new objects of its class, except the special creational method. This method either creates a new object or returns existing object if it had been created before.
You want a stricter control over global variables.
Unlike global variables, Singleton guarantees that there's just one class' instance. No one, except Singleton itself, can replace the cached instance.
Moreover, Singleton lets you easily change this restriction. For example, to allow any number of instances, you will only need to alter the code in one place—inside
How to Implement
Add to the class a private static field that will hold the singleton instance.
Define public static creational method that will be used for retrieving singleton instance.
Implement "lazy initialization" inside the creational method. It should create a new instance on the first call and put it into the static field. The method should return that instance in all subsequent calls.
Make class constructor private.
In client code replace all direct constructor calls with calls to the static creational method.
Pros and Cons
- Allows deferred initialization.
- Violates Single Responsibility Principle.
- Masks bad design.
- Requires special treatment in a multithreaded environment.
- Requires endless mocking in unit tests.
Relations with Other Patterns
- Singleton object can be mutable. Flyweight objects are immutable.
- There should be only one Singleton instance, whereas Flyweight class can have multiple instances with a different intrinsic state.