开发者_运维问答
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this questionWhen should we use the Singleton pattern and why?
http://sites.google.com/site/steveyegge2/singleton-considered-stupid
Why is the Singleton so attractive? I'll be the first to admit: I liked it too. No, scratch that - I loved the Singleton. It felt like an old friend from the moment I laid eyes on it. It was simple and beautiful.
I'll tell you why: it's because the Singleton pattern is a throwback to non-OO programming. It's a lifeline for people who didn't understand a single word that the Gang of Four were trying to say. I don't know how it got in there in the first place -- some political OOPSLA pressure, no doubt -- but it doesn't belong in there. It's Evil...
Here's the "short" summary...
a) I haven't covered even a tenth of the issues. But I'll name a few of them.
b) One is memory management; a Singleton is basically just a memory leak, if nobody is going to be using it for a while. But you have no idea when to deallocate it, because nobody's going to call you and say "nobody's going to be using you for a while!"
Besides, you can't tell who has kept around references to your Singleton instance, since you were pretty blase about handing it out, weren't you? (Note: Java's weak references can help with this issue).
c) Speaking of memory leaks, what if your Singleton has a handle to some limited resource, like a database or file handle? I guess you get to keep that sucker open until your program ends. Thank God C++ programs never last longer than about 10 minutes before crashing, usually from running out of resources, or from trying to access a Singleton that someone freed.
d) Another issue is that the Singleton design is syntactically noisy; most languages don't support it (well, Ruby does, sadly, but that was probably before Matz knew any better), so you have to stick in boilerplate code not only in the Singleton, but in everyone who uses it.
e) Then there's the subclassing thing. It's almost impossible to subclass a Singleton, and if you manage it, then you shouldn't have been using a Singleton in the first place. You don't even want to go there. I've walked roads that I dare not recount. Just pretend you can't do it, and you'll save yourself amazing amounts of pain.
f) static methods are as flexible as granite. Every time you use one, you're casting part of your program in concrete. Just make sure you don't have your foot jammed in there as you're watching it harden. Someday you will be amazed that, by gosh, you really DO need another implementation of that dang PrintSpooler class, and it should have been an interface, a factory, and a set of implementation classes. D'oh!
Don't suppose that's all. There are many other problems. For instance, try adding multithreading in and see what happens. Well, I'll tell you what happens: half the time, you get a Doubleton or a Tripleton, unless you're a synchronization expert, and having a Tripleton is about as desirable as having three Balrogs show up at your tea party. And even if you're a synchronization expert and get the double-check idiom right, you've still got one Balrog to deal with, and they're no picnic.
But these problems all fade into insignificance compared to the Big One, which is that the Singleton "pattern" encourages you to forget everything you know about OO design, since OO is hard, and procedural is easy...
Java Runnable is the best example of the Singleton Pattern. When you want to add a restriction which does not allow you to create more than a single instance of a particular class then it is better to implement a Singleton Pattern. Key points to implement singleton :
- Private Constructor
- Static Private Instance Variable of Singleton class itself
Public getter method only at very first time it will initialize above variable, and always return same instance of a Singleton class.
class Singleton { private static Singleton instance; private Singleton(){ } public static Singleton getInstance(){ if(instance=null){ instance=new Singleton(); } return instance; } ........ }
And for thread safety : getInstance() needs to be synchronized.
If you have a situation when exactly one object is needed to coordinate actions across the system, then you can use this pattern. A good example of this is the Facade, that is, Facades can be implemented as singletons because often one Facade object is needed across the system.
But in general, it's usually a bad practice and should be avoided, one big reason is it greatly inhibits extensibility.
In theory: when you need to restrict the instantiation of an object to one instance. In practice: never.
As said the intention of a singleton pattern is to ensure that a single instance of a class is instantiated.
The singleton pattern is considered as one of the "bad" patterns in the GOF pattern catalog since the singleton leads to coupling in code and makes (unit) testing of code hard. The latter point is not 100% true in (most) dynamic/loosely typed languages because you can monkey patch code.
Let's take a look at coupling: Every code piece that uses the Singleton is coupled directly to the implementation of the Singleton. This is hard/impossible to mock and since Singletons are often used for infrastructure services like a database access layer the unit that you want to test is coupled to the concrete implementation of the database access layer. But for a unit test you do not want to hit the database, you want to have some mock data access layer. You end up in a situation where you ask yourself why you used the singleton pattern.
I'd recommend the singleton pattern only for "simple" software but as we all know software has a tendency to grow. To start simple and end complex after some years.
When you don't want to create multiple instances of same type you need to go for singleton. But the same can be achieved if you use Static Classes. So the point here is it's not the only one instance but the control over instance creation, thus avoiding unneccessary consumption of precious resources.
Think of everything where more than one instance would be an error (inconsistence). THis could be an Application object (root object for a app) or a application wide securityManager etc. The singleton is just a way to enforce that at class can only have one instance.
The Singleton pattern is about to ensure a class has only one instance, and provide a global point of access to it.
When you want a bunch of different objects to be able to make reference to one single object. Maybe they want to all use the same PhysicsEngineDude or something... You don't want different objects having different physics models when they live in the same world!
When you just need one instance from a class. One of the best example is the logger. You just need an instance of it.
When only one instance from a class that is needed in the system.Since it has only one instance, so you can rigidly decide how the users can get access to it.
In software engineering, the singleton pattern is a design
pattern that restricts the Instantiation of a class to one object.
This is useful when exactly one object is needed to coordinate
actions across the system.Application needs one, and only one, instance of an object.
Additionally, lazy initialization and global access are necessary.
More here...
http://www.dzone.com/links/r/java_ee_singleton_design_pattern_introduction.html
精彩评论