Thursday 5 April 2012

Singleton pattern

This pattern:

  • disables creation of more than one instance of a class
  • provides global access to the class

A long time ago I used to be a big fan of singletons. I would have four, five, six...CThisManager and CThatManager "manager" classes that would be used from everywhere throughout the code without any control. But then I run into some funny problems during their construction and destruction if they would use each other and, design-wise, I realized that singletons were nothing more than just fancy global objects. Why would I allow some class to be accessed from everywhere? Why would I allow so many hidden dependencies? Difficult to follow, difficult to test.

Today, I am using only one class implemented as a singleton: a logger. Logger does not depend on any other class and all other classes (or most of them) are using it. Regarding other "manager" classes: I create a single instance and pass it down to its clients through dependency injection. Dependency is visible and under control. Just like objects' lifetimes.

Anyway, just to make this article complete, I am providing typical singleton implementations. There are many debates on their lifetime, thread- and exception-safety but the general conclusion is that they should be used wise, depending on the context.

Non thread-safe implementation:

Output:

main()
Singleton::getInstance()
Singleton::Singleton()
val_ = 0
Singleton::getInstance()
Singleton::getInstance()
val_ = 3

In order to make this class thread-safe, we need to put its construction inside the critical section:

Thread-safe implementation of Singleton class:


Obviously, critical section member must be defined in the source file (e.g. main.cpp):




Links and References:
Singleton Pattern (Wiki)
Dependency Injection (Wiki)
C++ and the Perils of Double-Checked Locking (Scott Meyers, Andrei Alexandrescu)
Is Meyers implementation of Singleton pattern thread safe? (SO)
C++ Singleton design pattern (SO)
Finding C++ static initialization order problems (SO)
Singleton instance declared as static variable of GetInstance method (SO)
Singletons Are Evil
Singleton: How should it be used (SO)
SINGLETON PATTERN - 1. THREAD SAFETY


No comments: