Original Post
Okay, i''ve just recently got my hands on the design patterns book that all the software engineers rave about, and its quite an interesting read.
I''ve developed on my own, or used several of the patterns defined in the book before i even knew they were actually documented somewhere (Specifically: factory method, bridge, iterator, adapter, strategy, etc)
Now i read the pattern on Singletons, and it smacked me that they are a lot closer to describing the problem i have been trying to figure out for a while than what I have thought up on my own.
However, there are a few issues with singletons that bother me, specifically while using subclassing.
In my problem, i require a virtual object which can be switched at run time, but remain as a global singleton object. This would be useful for hardware engines (grapics, sound, etc) which are abstract, or for math engines which use a specific optimised sub-set of the current processor (3dnow, mmx, or sse). Of these modules, it would only be desirable to have one in use at any given time.
The singleton pattern solutions for subclassing (since C++ does not support virtual static''s) strike me as hacks, almost. The first one explained in the book requires the base singleton class to be aware of every sub class singleton in the program. While not a large problem to a limited range program which will only use one or two specific modules, the problem appears when the client wants to modify an existing singleton and put it into a swappable external code module (such as a DLL). This would be impossible, obviously. This method also destroys object-oriented principles, as a base class should not know about it''s subclasses, and it would become a major detriment if the client is required to modify the base singleton everytime he/she wants to subclass it. There would be version control problems, and for a black boxed environment, this would be undesireable if you don''t want the clients modifying the base class.
The second solution presented in the book would be to have every sub class add itself to the global static registry, but the problem with this would require every subclass to construct itself on initialisation, and a graphics engine should not be created more than once at the same time, thus making this solution unworkable, not to mention slow, as the instance operation would be required to search a registry list every time it wants to access a virtual singleton.
And then there is the problem of initialisation variables. what if the virtual singleton requires class specific constructor variables? Surely we cannot expect the singleton base class to determine how a subclass is constructed.
Say we have a user launcher, which takes start variables from the user (from a file, or an OS specific window which requests variables, etc) to create a graphics engine. What if one graphics engine needs to know how to initialise the backbuffer type, but another does not? This information is obviously best put into the constructor, and the user launcher would construct the object and pass it into the framework.
This is impossible with singletons, as the constructors are protected.
I propose then, that there be a modification of the singleton class, a so called Global Registry or accessor. This would allow the user to create a virtual singleton and pass it into the global instance reference, as we only want to access the ''current'' module at any given time. This also solves the problem of the client managing several sub-singletons and swapping them into the global instance whenever a change is required, instead of the instance method re-checking of a change needs to be made every time the instance is accessed.
I realise this is not much different than using just a global pointer, and has no construction protection, but by using the instance method, global accessors can internally manage copies, whereas global variables cannot.
Does this sound like a good idea?
===============================================
Hurry up madness, hurry up disease,
hurry up insanity, hurry up please.
Hooray! I say, for the end of the world.