Singleton Considered Misleadingly Named

Summary: Some people think Singleton is for providing global access to an object, and that its uniqueness is only a side effect. Other people think Singleton is for ensuring uniqueness, and that global access to it is only a side effect.

There is a lot of dancing around this issue in SingletonsAreEvil and SingletonsAreGood but I think that the problem is one of semantics. I don't have many years of industry experience to back this up (0.75 years for those who are interested) but this may be one of those "naive child notices the GangOfFour has no clothes on" kind of things.

Premise: The point of the SingletonPattern is not to model an object of which there is only one instance, the point is to provide global access to a single instance of an object, i.e, the object effectively consists of GlobalVariable(s) and access methods. The fact that there is only one instance is merely a symptom of it being a global variable.

The GoF are quoted as saying the SingletonPattern is used to "ensure a class has only one instance, and provide a global point of access to it". I say it is used to provide global access to an instance of a class, a subtle but important distinction.

The problem with this pattern from my point of view (someone learning software engineering) is that it is represented a) as a method of modelling a single object and b) it has been blessed by the GoF therefore it is a GoodThing. Unlike, for example, GlobalVariable which everyone knows are to be treated with caution.

If you really wanted to create a single instance of a class you could make the constructor private and provide a oneOff() method which return a reference to the object the first time it is called and throws an exception on subsequent attempts. There you go, one instance that you can do with as you like. This of course means passing it as an argument to everything that uses it, but I never said it would be easy.

The conclusion: from this day forth the SingletonPattern should be renamed the GlobalObjectPattern? to reflect its obvious lineage from GlobalVariables. Any text teaching this pattern should note that it is has the same coupling and maintenance problems as using global variables (so that old dogs teaching themselves new tricks know to treat GlobalObject?s with care) and for beginners like my self the dangers should be spelled out. The only thing is whether this is now a pattern or an AntiPattern. Perhaps a UseItIfYouAreSureYouKnowWhatYouAreDoingAndTakeExtraCareInMultiThreadedEnvironmentsPattern?.

Well, what do you think?


The point of the SingletonPattern is not to present a globally accessible object. The real point is that there is only one instance of that class in the entire system (hence the name Singleton). The fact that the object is globally accessible is a side-effect of the fact that there is only one of it in existence: since only one exists, it stands to reason that code must access that instance, which in turn implies that the instance is globally accessible. I think that the fact that it is global is a matter of convenience.

A good example of a singleton might be a filesystem. Although it is globally accessible (by all FS code) the salient feature of it is that it is unique.

...until you decide that you want another filesystem object to represent the filesystem on another machine. Or you decide that you want a chroot-style filesystem. Or that you'd really like a virtual filesystem, possibly for testing, possibly not. In order to say an object is unique, you need knowledge about the entire program / system - exactly the sort of knowledge any given component is not supposed to have. But a call to a singleton's accessor represents that knowledge in code. How is that good OO design?

If you really wanted to create a single instance of a class you could make the constructor private and provide a oneOff() method which return a reference to the object the first time it is called and throws an exception on subsequent attempts. There you go, one instance that you can do with as you like. This of course means passing it as an argument to everything that uses it, but I never said it would be easy.

...and if you add a static method (in JavaLanguage) to the class and call that method to get the one instance you have a Singleton.


The conclusion: from this day forth the SingletonPattern should be renamed the GlobalObjectPattern? ...

Note that you can have global access to objects that are not single instances, too. So GlobalObjectPattern? would be at least as misleading. The example you provide, an enforced single instance without global access, is certainly possible but doesn't seem very useful. (Perhaps you could provide an example where it would be useful?) The point of patterns is to describe strategies which are useful enough that you want to use them repeatedly. The usefulness of the SingletonPattern hinges on two facts: that there is a single instance and that the single instance is easily accessible. The access doesn't have to be global; it could, for example, be private to a package.


If you're going to add a static method (in JavaLanguage), why not just use a utility class with all-static methods (like java.util.Arrays)? Seems like a good alternative to singletons, at least in languages that allow class methods/functions/whatevers and class variables/properties/whatevers.

...because then you can never replace the singleton type with a suitable replacement. By using a static method to retrieve the single instance we are effectively allowing ourselves the latitude to use the FactoryMethod pattern to replace the actual implementation of the singleton at some later point. Using a utility class locks us in - or at best means we have to, if we need to change the implementation, rewrite every static method to delegate to the new implementation. Having said all that, I strive not to have singletons in my code unless essential - they have caused me trouble many more times than they have aided me -- PeterSumskas.


I concur with much of the above. The SingletonPattern suffers from poor SeparationOfConcerns--namely, the concerns of what a class is designed to do, and managing access to it's instance(s). A well-designed class should work properly whether there are zero, one, or a gazillion instances to it.

My issues with singleton:

My suggestion instead: the InstanceManagerPattern.


Premise: The point of the SingletonPattern is not to model an object of which there is only one instance ...

I would disagree with the premise. A singleton is useful because it provides shared access to a unique instance. The pattern is applied when both constraints are required or useful. First some definitions. "Unique instance" implies state that is maintained between accesses. State is not unique configuration information but information that is dynamic and changes across the life of the object. There is usually a determination that it is "better" to maintain the state, rather than repeatedly recreate it from scratch. If this unique instance also needs to be widely shared, then a singleton is a simplified solution to making the object available while maintaining the state. If both criteria are not useful, then there are apporaches other than singletons that could be applied.


It seems to me that no matter how you define a singleton, the point is often to mitigate one or more of the problems with globals.


The main objection to singletons seems to be that, in the examples given for singleton use, it's possible that multiple instances might be wanted.

In these cases, grasshopper, don't use a singleton.

On the other hand, in the real world there are things of which there are only one, and a singleton provides the exactly right model for such things. Not all of them are discovered; some of them are defined: it may be a business rule that there shall be one and only one audit log (auditors like it that way). The most rational way to implement this is with a singleton. This, by the way, is nothing like a GlobalVariable, but a great deal like a global function, since the behaviour is more important than the state. It would be terminally smelly to not make it globally accessible. --MarcThibault


Premise: The point of the SingletonPattern is not to model an object of which there is only one instance ...

and I would add "and which may need to be implemented polymorphically at runtime". Thus, a singleton "getFileSystem" which at runtime may retrieve a windows file system, a unix file system, or a virtual file system according to the environment.

A pretty bad premise, given the Singleton Pattern intent in GoF:

Intent

Ensure a class only has one instance, and provide a global point of access to it.

If that's not what you intend, it would be good to give your pattern another name. --mt


Question posed above: "Perhaps you could provide an example where it would be useful?" I have used such a thing in a rendering graph which is composed of polymorphic nodes (scene graph elements). The root node is a Singleton but also a Node, and its children (and generally descendants) are also Nodes (but not Singleton). - Ryan Fogarty


RE: "...until you decide that you want another filesystem object to represent the filesystem on another machine."

At which point you use the ReverseFlyweightPattern.

Right?

--AnonymousDonor


See also: SingletonGlobalProblems, JavaSingletonPackage


EditText of this page (last edited April 3, 2010) or FindPage with title or text search