There is already an overwhelming amount of blogging and online articles on the subject of Singletons. These generally cover the issues of Why Singletons are Evil and, if so, what we should be using instead.
To remind ourselves, by definition (GoF), a Singleton must:
a) Ensure that only one instance of a class is created.
b) Provide a global point of access to the object.
The problem would seem to be the ‘global’ baggage that comes along with the ‘single instance’ aspect of the pattern. As Len Holgate so succinctly observed on his blog posting on the subject:
“Half of the classic singleton is a useful concept; a class that has only one instance. The other half is bollocks; providing a global way to access that single instance.”
In order to resolve the issue of ‘global’ access there are a number of alternative approaches available, including:
- Creating the object with local scope.
- Initializing at a higher level in the code and passing references to the instance around. This may be the best option if state must be preserved, if the object is expensive to create or for unit testing purposes, i.e. passing in a mock object.
However, reworking scope still leaves us with a some issues to resolve: we still are going to need something to enforce that ‘single instance’ restriction (putting aside the question I have seen raised of whether any object actually warrants having a ‘single instance’… but I digress), and at the same time we also need to ensure that this is done without any of the issues associated with the traditional GoF pattern.
One solution for this I came across recently is to use Singularity instead. This is an improved alternative to Singleton which restricts any class to a single instance, just as we require.
The issues of scope (by providing optional global accessibility), lifetime (use of familiar create() and destroy() methods), unit testing (can be created before each unit test and explicitly destroyed afterwards) and initialization (any constructor can be used, i.e. not just the default constructor) appear to be all neatly addressed.
Configuration of a class to be used as a Singularity is straightforward too: simply declare the singularity class as a friend and make the constructors private.
This would also seem to provide another advantage over Singleton: should the requirement for the class to actually be ‘just one instance’ change and you suddenly want more than one, the reworking of the code should be reasonably straightforward. It is not unknown to think you could never need to have more than one instance of a class, and then later find that you do.
Singularity is currently awaiting formal review for Boost, and if accepted, would lead to inclusion within the library.