Generally, the singleton pattern is implemented by creating a class with a static method that creates a new instance of the class if one does not exist. If an instance already exists, it simply returns a reference to that object. To make sure that the object cannot be instantiated any other way, the constructor is made private. Is there any other way for creating a singleton ?
2 Answers
A static public read-only variable
(if supported by your language)
C#:
public static readonly MyClass singleton = new MyClass(); // create at class/assembly load/access
Java:
public static final MyClass singleton;
static {
singleton = new MyClass();
}
C++:
// header
class MyClass {
public:
static MyClass singleton; // value, created before main, or at dll load
static MyClass const * singleton; // const ptr to non-const value, created before main
private:
MyClass();
~MyClass();
MyClass(const Myclass&) = delete; // c++11, remove default implementation
}
// in cpp:
MyClass Myclass::singleton;
MyClass const* MyClass::singleton = new MyClsas;
With most compilers/languages, this avoids the create-on-demand problem which requires thread-locking and order-of-initialization/destruction problems.
Explicit via main() or dependency-injection
However, my preferred way of doing singletons is to create a field/property somewhere and initialize that explicitly (in main or via some dependency-injection framework. This helps quite a bit with managing many singleton-types, especially with testing.
You could additionally test and prevent set the singleton property from being set more than once if you wanted to, at least when not running tests.
int main()
{
// Just set it. Use discipline to prevent others
MyClass.singleton = new MyClass();
// Use function, then we can enforce set-only-once, if required
MyClass.setSingleton(new MyClass());
// dependency injection via env-vars! :)
MyClass::setSingleton(ClassFactory::create(getenv("MYCLASS_SINGLETON_TYPE"));
mainLoop();
}
Store the singleton somewhere else
It can often be convenient to have a "manager" or "registry" or whatever to hold all the global objects. Then that class could be responsible for creating/setting up all your big singleton-ish objects that you need.
That way, the class that you use as a singleton doesn't need to care about being a singleton. Very useful when testing or "reset" style scenarios.
It also helps by centralizing all these "big" objects somewhere so that the global state can be found and managed in a single place, rather than between 5-25 different classes all over your application.
Comments
You can synchronize within the method the most common pattern called double checked locking.
http://en.wikipedia.org/wiki/Double-checked_locking
Here there are some code samples about double checked locking.:
http://javarevisited.blogspot.co.il/2014/05/double-checked-locking-on-singleton-in-java.html
EDIT
The key benefit of using double checked is that you can use run the function with more then one thread while only the critical part of creating the new object is done under lock.