Singleton Pattern is where only one instance of a class can be created.
It is known that this is one of the simplest pattern available, but There is more to this pattern than meets the eye. UML diagram might be simple, but there is much more to understand in the implementation and usage.
What are the situation where we should use only one object for the whole program.
- When using thread pools.
- For caching.
- For dialog boxes.
- When using logging.
- When using device drivers printers,graphic cards and etc.
Using singleton pattern in above situation would help to avoid issues such as,
- Inconsistent results
- Overuse of resources and etc.
One might ask, can't we use a global variable for this? why do we need a design pattern?
Singleton Pattern is a time-tested method for ensuring only one object gets created
Global variables are created when the application starts, regardless of whether we need it or not. If that objects uses some heavy resources, then the situation get worst. Singleton Pattern is not only about preventing more than one object, it is also about how to properly manage that.
How to make a class Singleton
No public constructor means there is no way to create an instance of this class. Only way is to call getInstance and get the existing unique object.
Qualities of Singleton
- Creates a unique object.
- Singleton class is just like a normal class, but can create only one instance.
- By using this pattern, we can avoid bugs and conflicts in the program.
- Constructor of a Singleton class in private.
- When we need an instance of that class, we don't create. We request.
- Singleton class has a static method to return the instance (example :- getInstance()).
Example :-
This pattern can be used to share the configuration values through out the application. By implementing configuration class as singleton, we,- Provide a global point of access to configurations.
- Provide a caching mechanism (If we are getting config values from a db or a service call, this mechanism avoids calling the db or the service each time a config value is requested.)
Class A.java
Class Configs.java, which is the singleton class.
Class B.java and C.java, which uses the config values.
ALERT
There are some series questions we need to ask before summarizing Singleton Pattern. Could the addition of threads to the program cause any issues? Purpose of using Singleton pattern is to use a unique and single instance of a class throughout the program. But when there are several threads executing the same code, there is a chance that several instances of this singleton class can get create. Problem occurs in the IF condition where it checks the null value and creates the object.
To make the Singleton Pattern robust, we need to make it thread safe. We can make it thread safe by making getInstance() a synchronized method.
synchronized Key word prohibits two thread accessing the getInstance() method at the same time.
synchronized is needed only in the first time and no need once the unique instance is created. Using synchronize is very expensive in java. So we have to look for other options. Read more about why synchronize is expensive here, LINK
- If performance is not an issue in you application then use the above method, which is using synchronized key word in getInstance() method.
- Create the singleton object in a static initializer.
Here the unique instance is created when the class loads. Instance is created before any thread is start using it. This method is suitable when,- If the application always creates and uses an instance of the singleton class.
- If creation and the run-time aspect of the singleton object are not formidable.
- Use double-checked locking : In this method we synchronize only the section we want, using Synchronized Blocks. Here double-checked locking means, check if the instance is created, if not, then synchronize. Read more about java synchronized blocks here LINK
In the getInstance() method- line 3 : volatile means, appConfig variable is visible to all threads.
- line 10 : We check appConfig for null. If appConfig is null, then only we create synchronized block.
- line 12 : Inside the synchronized block, check again for null. If appConfig is null, then create an instance.
If you are concerned about the performance of the system, this is the method you should use to implement singleton.
NOTE :
- Double-checked locking doesn’t work in Java 1.4 or earlier
- Using multiple class loaders may break the Singleton Pattern.
- Need to create a registry of Singletons to defeat the garbage collector for JVM earlier than 1.2. Read more about Java Classloader here LINK
ALL CLEAR
Even-though Singleton pattern seems like a simple pattern to study, there are so many things we need to consider when using it. Intention of this article is to provide the readers with all the essential information needed when using singleton pattern. But things doesn't stop from here, we have to keep studying update our knowledge. There might be better ways to achieve, what we are trying to achieve with Singleton Pattern.
Reference :
- Head First Design Pattern : 5. The Singleton Pattern: One of a Kind Objects
- Singleton Pattern : http://www.oodesign.com/singleton-pattern.html
Comments
Post a Comment