A Singleton is a design pattern that allows for a One and ONLY One Object instance of a class to be instantiated within the memory of a process using object oriented programming concepts.
Maybe people will ask, well why can’t I use a Static instance of a class in my program as a field or data member? Well, you can, however in larger scale programs, you may not want to have to pass around the static instance of this class from class to class or method to method. This often will over complicate your code and make it harder to maintain.
Or, can’t I just use all static fields/data members and methods/functions in my class to accomplish the same thing? Again, you can, however you lose a lot of the benefits of having an true SINGLE instance of an Object. You are now dealing with a object that is less flexible than if you made a Singleton instance of that class.
There is some debate on this between programmers whether you could just use all static methods and fields verses a singleton, but a singleton’s behavior is more predictable across languages, because the design and ordering of creation is controlled by the programmer instead of the system. So my own preference is not to use a class with all static members and go with a Singleton.
I also personally feel, that a class with all static methods, should be restricted to classes that only contain helper methods, such as a class that contains String manipulation helper methods. I usually have this type of class in my systems, called “StringUtils”. All methods are public static, and stateless. They are used to perform a common string manipulation function and return.
By using a Singleton, you have more freedom to design the true behavior of your class, including how the class is created and initialized. This where the Factory of Singletons comes into play a well. I usually like to create a Factory which itself is a Singleton, that creates a Singleton. This factory than can be used to return an implementation of a interface which a range of Singletons could define the implementations of. The factory can also be used to correctly call the initialization methods after the “GetInstance()” static (and atomic aka synchronized) method is called to obtain the instance of the Singleton. This is perfect in case you need to call a specific initialization function or set root parameters ton the Singleton that you don’t want the user of your singleton code to have to deal with.
The single most important factor that makes a class a Singleton is a “private constructor”.
By having a private constructor, there is NO other Class except for itself that can create an Object instance of that class.
The private constructor is not by itself how a Singleton is built, technically, I could have a private constructor and still have a static method that returns unlimited new and distinct instances of the class, so we need a “Get Instance” method, basically a Factory method, that ensures that One and Only One instance of the class we are trying to make a singleton is created in memory for a particular process. Because the constructor is private, the only way to access this Get Instance method is to make it public and Static. (I recently read a post of Java’s facebook page asking for a one line explanation why I would use the static keyword to modify a method signature. Well, simply: We use the static modifier on a method to make that method available at the Class level. This means that there’s only one instance of that method in memory for all object instances. This also works to our advance for the singleton implementation, because I can’t create a object instance of the singleton class myself, so calling public static methods is the only way to interact with the Singleton, before I call the Get Instance method which will return the one and only Object instance of the singleton class.)
This is usually done by using lazy instantiation in the Get Instance Method. Lazy Instantiation or Lazy Initialization is when in programming, we do not “pre-create” or pre-initialize an Object or other structure or section of code until the first invocation of usage of that object, structure, or code is required. This is a great concept, when working with limited resources such as Memory, or when perhaps, we don’t know if we ever need a instance of something, and why bother wasting processing cycles and RAM on creating that object.
The third and final component that makes a class a singleton, is a private static field whose data type is the Singleton’s class itself. This field would be set by the lazy instantiation code of the Get Instance method. And is used in the lazy instantiation check, if it is NULL, call the private constructor and set the private static field. Then simply always return the private static instance of the singleton class. This causes our class to be a singleton. The only object instance that exists, and will ever exist while the process is running is the private static instance of that class.
The Get Instance method also needs to be atomic or synchronized, to make sure it’s thread safe. If not, technically two methods calls to the Get Instance by two separate threads could potentially create two or objects of the singleton, and all of those objects would eventually be lost once the threads stop referring to them, and only the last one that set the static instance field of the Singleton class instance itself would survive, and this potentially could cause data corruption or other weird runtime related issues, because we are assuming you need a single instance of an object globally for some critical reason, not just for fun…
Perfect example of a simple Singleton: “GlobalMap” –
/* * Created on March 1, 2004 */ package com.roguelogic.util; import java.util.HashMap; /** * @author Robert C. Ilardi */ public class GlobalMap { private HashMap<Object, Object> cache; private static GlobalMap globalSpace = null; private GlobalMap() { cache = new HashMap<Object, Object>(); } public static synchronized GlobalMap getInstance() { if (globalSpace == null) { globalSpace = new GlobalMap(); } return globalSpace; } public synchronized void clear() { cache.clear(); } public synchronized void store(Object key, Object value) { cache.put(key, value); } public synchronized Object retrieve(Object key) { return cache.get(key); } public synchronized Object remove(Object key) { return cache.remove(key); } public synchronized boolean containsKey(Object key) { return cache.containsKey(key); } }
syntax highlighted by Code2HTML, v. 0.9.1
As you can see from the simple class above “Global Map”, the idea was to create a Singleton Hash Map, so that we could share the HashMap through a java process without having to pass it from class to class. And in large programs with 100’s or even 1000’s of classes this would not only be impractical, but bad coding practice. The Global Map uses the 3 root concepts of the singleton design pattern:
1. Private Constructor: Line 18 –
private GlobalMap() {
cache = new HashMap<Object, Object>();
}
2. Private Static Singleton Class Data Type Data Member: Line 16 –
private static GlobalMap globalSpace = null;
3. A thread safe Public Static Get Instance (factory method), which uses lazy instantiation to create and initialize the private static singleton class data type data member: Line 22 –
public static synchronized GlobalMap getInstance() {
if (globalSpace == null) {
globalSpace = new GlobalMap();
}
Factories of singletons are simply Factories that return instances of singleton implementations. A factory of singletons could simply always return the same singleton implementation or it could based on criteria return different singleton implementations.
The advantage of using a Factory that creates the singleton, is that the factory could contain additional logic outside of the singleton that calls certain initialization methods and sets configuration settings on the singleton at the first call to the “create” method in the factory so that the singleton is initialized once and only once. This abstracts the responsibilities for initializing the singleton correctly on the first call to the Get Instance method on the singleton itself, away from the end users of your singleton class.
Technically you could put the responsibility of calling certain initialization methods on the singleton after the first call to the Get Instance method on the singleton in the hands of your users, but then they would have to put counter or flags to indicate when the first call of Get Instance was called. This in a sense negates some of the direct benefits of a singleton, and therefore wrapping this logic yourself in a Factory if a much better choice.
However a Factory of Singletons should only be used if you need a complex initialization routine after the call to the private constructor of the singleton that requires a lot of outside input or parameters to be set on the Singleton that is too cumbersome to be done within the singleton itself.
There’s also a neat trick I have used in the passed when combining Factories and singletons. Sometimes I remove the Get Instance method from the singleton itself, and instead create a “Protected Constructor” instead of a private one. Although this technically means it’s not a true singleton, and in a language like Java, this allows “friends” or classes that exist in the same package to invoke the constructor directly. If you put the Factory of the Protected Constructor Singleton in the same java Package, it can then be responsible for creating the singleton object instance instead of the singleton itself.
Also, within a Get instance method in the singleton class itself, this basically forces the users of your code to ensure they go through your Singleton Factory always instead of trying to construct the singleton themselves and possibly messing up the initialization procedure which should be done by calling the create method on the Factory instead.
I think this shows the real power of design patterns, they are more guidelines than anything else, and you can use them in combination or modify them to suit your needs.
My posts on design patterns seem to be the most popular posts on my blog to date (besides my Tesla Coil post ), so I’m definitely going to write a post on Factories and Abstract Factories in the near future. Please stay tuned for that! In the mean while, please feel free to check out my design pattern post on Adapter Factories.
Just Another Stream of Random Bits… – Robert C. Ilardi
Great Read. The only way GolbalMap would cease to be Singleton is by cloning, reflection and serialization each of which need to be handled separately.