
Matt, I am glad your interest is piqued (and I learned it is not spelled peaked). I have posted the source file, and a Boost Test unittest file in the Vault in the folder Singularity. Commenting on your first and second point, the Singularity Pattern (as I am calling it) is flexible enough to allow constructing the class with any supplied constructor. It is true you can construct a Singleton using the default constructor, and pass in dependencies via member functions, but you cannot pass in references this way. Singularity provides this flexibility which Singleton does not. I agree with you that the lifetime of Singleton is difficult to manage. The lifetime of a Singularity is bracketed by the calls to create() and destroy(), just like any other object created with new() and delete(). The difference being that new() can create any number of a objects, and Singularity::create() will only allow one. I look forward to your feedback on the pattern. I recommend looking at the usage in the Singularity/singularity_unittest.cpp file before studying the implementation. Thank you, Ben Robinson, Ph.D. On 6/23/2011 1:08 AM, Ben Robinson wrote:
The Singleton pattern does have its uses because it guarantees a single instance of a class. However, it suffers from three weaknesses:
1) Encapsulation: Singleton provides global access to the class. Some may view this as a feature, but advocates of unit testing, and dependency injection would disagree. 2) Initialization: Singleton restricts the class to the default constructor. This makes Singleton unusable for classes which require non-default constructors. 3) Lifetime: Singleton introduces lifetime management complexities (for a detailed discussion, see Chapter 6 of Modern C++ Design by Andrei * Alexandrescu*).
I have formalized what I believe is a novel design pattern, which guarantees a single instance of a class, but which does not suffer 1-3 above. And unlike Monostate, this pattern I propose does instantiate a genuine instance of any class, using any one of its available constructors. I hope this inquiry peaks your interest.
I've often wondered about singleton's bad rap (other than the difficulty of making them reliable in C++). I use a singleton from the boost vault for hiding implementation details of globally accessible interfaces (e.g. an interface to access information about elements of the periodic table when I don't hard-code all the constants). This usage is unit testable as long as the implementation details can be thoroughly tested through the interface. It could support DI too if the dependencies are given to the singleton's methods instead of at construction. I don't understand weakness #2. My usage of singletons makes initialization an implementation detail. Construction is not part of the singleton's interface because constructing it different ways from different parts of the program would mean having more than a single instance. #3 is a indeed a bitch with C++. The boost vault solution I use makes it quite easy to chain singletons though. Nevertheless, my interest is piqued. Thanks, -Matt