
Tobias Schwinger <tschwinger <at> isonews2.com> writes:
Anthony Williams wrote:
The responsibilities of a Singleton. Citing another post (sorry for the redundancy -- I think I'll add a brushed-up version of this list to the documentation):
1. Making the user implement a class 1.1. encourages a well-defined object interface,
Only if people can manage to use one singleton per role.
1.2. embraces a design that can easily be changed to use non-globally scoped objects instead, and
I disagree there. Uses of singletons cannot easily be changed to use non-globally scoped objects.
1.3. prevents pollution of the global namespace.
Not really: you have to provide a class name rather than a variable name.
2. Providing on-demand initialization 2.1. makes non-trivial construction work with any ABI's shared libs, and 2.2. automatically resolves dependencies between Singletons.
As I mentioned before, this is orthogonal to Singleton: the responsibility of singleton is to ensure there is one and only one instance, not to provide on-demand initialization. This is also easily provided by other means.
3. Ensuring a single instance of the Singleton class 3.1. allows to properly model unique facilities (hardware, registries, etc.) in an object oriented fashion, and
This is the crux of the matter. Just because there is only one printer, doesn't mean that you have to enforce a single instance of the Printer class. Just create one instance, and pass it down with dependency injection.
3.2. allows to encapsulate a well-defined access point in the first place.
It might be well-defined, but I'd argue that it's not well-designed.
I've written code that used singletons (and regretted it later), and used code that other people have written containing singletons. So you should like this library: The design chosen allows you to easily substitute Singletons with Smart Pointers.
I disagree. If people know something is a singleton, then they don't bother keep the reference around, as they can get it again later. Changing code that does that to code that can use a passed in instance requires adding parameters and/or storing references. You can't just change uses of a singleton to use a smart pointer instead without thought to *how* it's being used.
I won't argue on this one. I can imagine that having to refactor a mess like this is a most unpleasant experience.
Still it's not the fault of the Singletons but of developer's laziness: At least the developers in the project you mention had a choice whether to write flexible code or not. With globals and static functions, they wouldn't have had a choice but to make a mess.
Singletons *are* globals. Anthony