Almost every use of singleton I have encountered was best replaced by an attribute accessor in a higher level object that is then either
- explicitly passed around via a parameter, or
- used via a dynamically bound variable (possibly within a thread-safe wrapper)
In either case, the GlobalVariable
reference is gone.
I am putting this at the top as it is one of the best articles on the singleton I have seen.... http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx
I too was once a singleton lover. If you prevent yourself from doing singletons for 1 year straight, you will find out one thing....singletons are evil. If you have not prevented yourself for 1 straight year, you have no right to talk. That is like never eating ice cream and saying you know the fries are better. Maybe the fries are better but shut up until you have tried the ice cream first!
You can still represent the real world and only have one thing (though naturally you just need to make sure you only instantiate one). That is usually done in some top level module and passed down to services (ie. Depenency Injection). The worst thing I have found out about singletons is when it comes to wanting to write reset code (specifically in tests). In a no singleton system, I can just new Service() and if it was designed right, the use of static keyword is rarely used except maybe for constants and all state will be reset....Great for the test setup method. --
So, you are suggesting that your reset is accomplished through the constructor? This forces the constructor to look for previously existing conditions on the real world device and do the appropriate things to knock the device down before setting it back up again. Okay, I can buy that. Now, how do you "make sure" that only one instance of the device is present in your system?
I've run into the same problems and a few more. I'm writing up a paper about it. -- MichaelFeathers
- I'd be interested in seeing that paper when it's finished. Are you covering any refactorings to reduce the bad consequences? -- RogerLipscombe
- Michael, how's the paper coming? -- FrancisHwang
I see singletons as the cause of a dichotomy within an ObjectModel
. All of a sudden there are two types of objects, those that can be instantiated in a standard fashion and those that cannot be created at all. I would personally rather use a container which governs the number of a given object that can exist in a system and acquire the objects from the container. -- JohnHarby
I've never used a singleton to make sure there was only one of something. Singletons usually are used to provide a single point of access to a global service. I always make the singleton separate from the class itself so the class can be used any way you want. The singleton can then use the class. The singleton also doesn't have to instantiate the object. It just has to provide access to the object. The object returned can bet set by any means necessary.
- That's more like the different, but related, FactoryPattern.
- Actually, you are using the singleton pattern to ensure there is only one of something. Your error is in considering that something to be the behavior provided by the service component rather than the behavior provided by the service facade or service locator. An object that can only be instantiated once that creates a new GUID everytime its GetGuid?() method is called is a singleton by virtual of its inability to be instantiated more than once, not because it does or doesn't work with the same components internally, or prevents those components from being created and used outside the context of the singleton.
"Use Your Singletons Wisely" http://www-106.ibm.com/developerworks/webservices/library/co-single.html
I wrote the article after seeing at least two dozen instances of the following code deep within the server of the project I was working on:
MySingletonObject mySingletonObject = MySingletonObject.getInstance();
MyApp.singletonObject = mySingletonObject;
The rest of the programmers were encouraged to use the singleton objects through M
yApp rather than directly. In that case, why the hell are they singletons?!
I shook my head for minutes when I ran across this. Then I started ranting. Then I started writing. -- JbRainsberger
Looks fine to me - keep the structural detail in one place to simplify changing the multiplicity later. Works especially well with threads. Still, ranting is good for you.
Let's assume that all singletons are evil. We observe that every entity is a singleton. From this we can conclude that everything is evil, including the wiki at c2.com. But if the wiki is evil then it must be lying when it calls singletons evil. This is a contradiction, and so the original assumption must be wrong. Therefore, it follows that singletons are not evil. -- AsimJalis
I don't think your argument is sound. The problem with your argument lies in the assumption that every evil thing never tells the truth. Something like this makes the problem clear: all entities are singletons; all singletons are evil; therefore, all entities are evil; all entities are evil; all evil things are things that tell only lies; therefore, all entities are things that tell only lies; the wiki at c2.com is an entity; all entities are things that tell only lies; therefore, the wiki at c2.com is a thing that tells only lies (there should be more about deducing that lies are untrue, the statement about singletons being evil is a lie, blah, blah, blah). The basic problem is that evil things will quite often tell the truth. I don't think it's hard to think of situations in which truth telling in no way impedes the execution of evil or the presence of evilness.
Comments applicable to JavaLanguage
- Subsystem's coupling to Singleton's Class Name.
- Singletons aren't polymorphic.
- "All of a sudden there are two types of objects, those that can be instantiated in a standard fashion and those that cannot be created at all." -- JohnHarby
- "The singleton also doesn't have to instantiate the object. It just has to provide access to the object. The object returned can bet set by any means necessary." -- JbRainsberger
In a good framework, Singletons are never tried to be instantiated twice (leaving a remote occasion of two or more threads doing that). Assuming this, we just need a safe guard of not having another instance.
Possible Solution: SingletonsAreGood
Doesn't a CeeSharp
static class, with its static constructor, provide all the functionality you would ever need from a singleton? -- John
Static classes lack polymorphism - you'd have to wrap your static methods in an object if you ever wanted to use it to implement an interface. Still, C# does provide a useful implementation of a singleton through the static mechanism - static constructor can be used to construct a private static member through a protected constructor, which can, in turn, be returned with a property. -- MartinZarate
I hereby christen the overuse of Singletons as the SimpletonPattern
Independently discovered by SteveYegge: http://steve.yegge.googlepages.com/singleton-considered-stupid
Singletons are ok when they reflect a real-world thing that you only have one of, but where you might want polymorphic implementation at runtime. The obvious case in point and the usual example used to justify them is the i/o environment. Thus, reasonable candidate singleton objects are "the current security context", "the available filesystem", "the screen on which you can paint stuff", and (in JavaLanguage
) "The JavaVirtualMachine
running your code".
In most cases this is just an artificial limitation. The examples given makes perfectly sense to have multiple instances of. You just have to open your mind to see the possibilities.
Wikis are evil since all the comments in this one destroyed the article - Satan
Discussion about refactoring this page: SingletonsAreEvilPageRefactoringNotes