Necessary singletons are a sign that your language/library either embraces "everything is a class" so you have to make vacuous singleton classes to get full access to the language, or it is lacking a sufficiently powerful module system so you have to implement an ad-hoc one yourself using classes.<p>Unnecessary singletons are usually a sign that someone, somewhere designed a way too general system that allowed multiple instances of something, then nobody ever used that feature, then someone else came in and made things a bit saner by adding a singleton constraint, leaving vestigial object-ness and meaningless pointers being passed around everywhere.<p>In a perfect world with perfect programmers you'd never see one so the instinct that they smell bad is correct.
Downvote away -- I know I deserve it, but I need to say this:<p>Whenever I see a discussion of good software design principles given by a PHP programmer, with PHP examples, I roll my eyes and press Back.<p>Rightly or wrongly, the thought that goes through my head as a former PHP programmer (from versions 3 - 5.x, ending in ~2010) is something like, "if this person knew anything about well-designed software, they'd know enough to use a well-designed language."
There is another argument against singletons. They destroy design information:<p><a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2012/12/global-variables-destroy-design-information.html" rel="nofollow">http://michaelfeathers.typepad.com/michael_feathers_blog/201...</a>
I am not a big fan of "getInstance". For a session it should be named something like "defaultSession". It is perfectly reasonable that you later want to add a separate session that requires HTTPS only cookies, in which case it could be called "secureSession".
If we're on the subject of anti-patterns, should GOTO really never be used, in any situation?<p>I remember writing some code in C a few years ago and I needed a place in a function where cleanup is performed, and in case there were errors caught in multiple places before you get to the cleanup area, I used a goto statement to jump there after printing the error message and turning on a special error flag.<p>How would you solve that problem without goto?
My problem with most singletons is that they are a half-way solution for a developer unwilling to commit and accept that sometimes a bit of global state isn't the end of the world.<p>Static fields and static methods on classes should be used sparingly, but if you're going to use them, just use them. Why half-assedly try to hide the fact that you're using them by wrapping them into a singleton?<p>This is a(nother) thing I like about Go, the design of the language allows for the fact that sometimes a function is just a function and doesn't need an object receiver and maybe it even modifies a package level global, so what? Just make sure you properly handle multithreading situations. In Go code you don't find a lot of patterns where people are trying to sweep what they are doing under a rug in order to not anger people who accept "common wisdom" code design guidelines as absolutes.<p>If you need to write "dangerous" code (and sometimes it is best to write "dangerous code"), do it in the open, out in the light of day, that way at least it can more easily be reasoned about if someone does hit a snag in it.
Singletons are easy to implement, simple to understand and have no performance penalties. They don't need to be defended. If they work for your project, use them.
So Eric is sort of right although he doesn't explicitly state it: Singletons <i>may</i> provide a decoupling point nearly identical to dependency injection when designed with care. But that's not really the problem, and he stops with an argument that is compelling to someone in 2002 but not so compelling for someone from 2012.<p>The reason we prefer non-singletons to singletons are as follows:<p>• Most languages do not provide very good ways to prevent singleton collision. As software has become more complex and open source's success increases the size of the average dependency tree, this problem is exacerbated.<p>• Singletons force you to confront all the problems shared state concurrency has to offer, with almost no support. DI objects tend to be isolated from one another and do not run into that level of complexity so soon.<p>• Singletons tend to make it harder to test code unless your language has a method for overriding or mocking singletons within a dynamic scope (or static type checking between types with liskov-substitutable signatures). The most classic exampe of this is one of the most prevalent singletons: your system clock.<p>Knowing what we know now about how successful software projects tend to be confronted with expectations of concurrency, parallelism, robustness in the face of reuse, and testability; singletons offer a lot of costs for very transient benefits.
I generally prefer Lisp-style ✲dynamic✲ variables. They basically work the same way singletons do, but they can be set and reset at a block-scoped level (great for test mocks and the like, and makes your control flow easier to understand), and they play much better with threads.<p>Rust doesn't even have singletons or global variables, since they aren't threadsafe. It has thread-local storage, which dynamic variables are built on top of.
This is a good read on singletons.<p><a href="http://www.object-oriented-security.org/lets-argue/singletons" rel="nofollow">http://www.object-oriented-security.org/lets-argue/singleton...</a><p>"Singletons are possibly the single greatest obstacle to good object-oriented design today. They are often at the root of huge intractable design flaws in large systems, and yet many programmers continue to use them and even insist that they are a good design pattern. Many programmers point to the fact that the singleton pattern is a prominent part of the book Design Patterns, but don't realize that at least one of the authors of that book (Erich Gamma) is on record saying that it shouldn't have been.<p>We argue that Singletons are almost always bad design and almost never needed. In the few cases where singletons seem necessary, the "environment pattern" offers a reasonable alternative. Therefore, we recommend that programmers always avoid singletons and that programming languages ban them or at least provide an option to ban them."
I prefer to mix both dependency injection and singletons for the best of both words. Classes accept dependencies in their constructors but as optional parameters -- if the parameter isn't provided, a default reference is pulled from a singleton.<p>It saves a lot of extra typing when 99% of the time your dependencies are fixed.
Singletons, globals/statics, and dependency injection all seem to be solutions to the problem of making objects find each other at runtime.<p>Maybe it's time for a dedicated language feature to solve that problem? For example, each object could carry an implicit reference to an "object pool", from which it can fetch other objects by their class/interface. If an object constructs other objects, the "pool" gets passed along implicitly. Test suites could use "pools" filled with mocks. And unless I'm missing something, the presence of all required dependencies could be statically checked at compile time.<p>Basically it would be like Lisp's dynamic variables, but based on the construction hierarchy instead of the call hierarchy. What do you think?
The main issue I have with singletons is that <i>any</i> mutable global state prevents your application from being first-class within its own runtime environment.<p>This is of course useful for unit testing, but also reduces hidden state dependencies between submodules.
I've been of the opinion for a while that static variables of any kind should be avoided except for const data (tables, constants, etc.). They make code very difficult to impossible to port to multi-threaded environments, and make it hard to cleanly instantiate and then clean up a module within a larger program. Even things that feel like they should be global should be contained with a global context container that can be cleaned up.
I can't speak to server side development, but for ui applications, storing your models in a singleton can save you a lot of time. When you're developing apps its very easy to get stuck in a mindset that you only need certain data for each screen, but the truth is the data for one area will inevitably bleed over into other areas, and having a good way of updating and reflecting data to the areas needed is the sign of good architecture.
I've posted a follow-up to this that broadens the ideas of Singletons for general PHP use. Using abstract classes and inheritance, it's also possible to unit test the code contained within a Singleton. The follow-up is here: <a href="http://news.ycombinator.com/item?id=5023027" rel="nofollow">http://news.ycombinator.com/item?id=5023027</a>
Is it just me or did he never actually address the dependency injection complaints? It read like he spoke glowingly of how dependency injection decouples your code and makes your blissfully flexible and then nothing. Was his counter argument just that sometimes you <i>need</i> to be less flexible?
> Think of every time you’ve used the global keyword when working in WordPress.<p>I pretty much stopped reading there. Referencing WordPress when making a point about software design does not strengthen your point.<p>Singletons are the antithesis of dependency injection.
The number of replies defending PHP make me think that HN is very close to becoming a useless place, dangerous even, for obtaining programming (and probably other) advice.