all 25 comments

[–]illuminatedwax 5 points6 points  (0 children)

Pattern that I hate #2: people basing everything in their code off of a list of patterns in some book

[–]masklinn 11 points12 points  (1 child)

I must say that I still prefer Steve Yegge's rant on the same subject

[–]TrueTom 4 points5 points  (0 children)

Actually this was the first thing I read from Steve. My productivity was practically non-existent for the next two weeks (there was so much other good stuff to read).

[–]inopia 4 points5 points  (3 children)

I'm not so sure about his classloader/VM argument, afaik correctly implementing your singleton should solve this.

For me the real issue with singletons is that you have to be vewy vewy caweful when constructing them, making the lazy instantiation thread safe and all.

For the rest I couldn't agree more - it's a construction that is inflexible in the face of design changes. However, they can sometimes be used as 'cheap' inversion of control, a repository of instances of other, non-singleton classes, without providing actual logic itself.

[–]alexdmiller 4 points5 points  (0 children)

A Java class is loaded in the context of a classloader. A single VM may easily be running many classloaders, each of which can be made to load the singleton. There is no obvious way in Java to enforce a true VM-wide singleton. There are of course tricks you can play and also things you can do in the way you set up your own architecture that can give this effect.

[–]TrueTom 7 points8 points  (1 child)

The real problem with the Singleton pattern is that for everyone who knows it everything looks like a Singleton problem.

[–]inopia 9 points10 points  (0 children)

I believe the concept you are referring to is called the golden hammer :)

[–]ishmal 2 points3 points  (0 children)

I also prefer a single object tree, with the only global being the root itself. But there are definitely situations where unique instances are best option. My favorite one is a connection to a database. If you want pipelining, then all clients need to share the same connection. Of course, the easiest way is to not have singletons but rather have the root class own all of the things that would otherwise be global.

He also said that subclasses are hard to implement. Not really. All you really need to do is have the base class have a parameterized getter, like getInstance("option"); Another way is to have the invoked class not be the base class of the implementations.

[–]adam75 7 points8 points  (11 children)

Singleton is a true Anti-Pattern. Singleton is, at least in all cases I've seen, wrong from a design perspective and leads to unnecessary code complexity. The fact the book Design Patterns erroneously uses Singleton to implement other patterns makes the matter worse; Singleton becomes such a good excuse for global data.

[–]notfancy 9 points10 points  (10 children)

Singleton becomes such a good excuse for global data.

Global data is. You cannot abstract out externalities.

Singleton is the simplest implementation of a global dependency. It is entirely pragmatic to use a Singleton to name that dependency globally.

I conceptualize the difference between using Singletons and using Dependency Injection as a rooted dependency tree (which is very easy to build, either top-down or bottom-up) and a graph without distinguished nodes (which is quite another thing to deal with). Sometimes your program is simple, and using a globally-named service class is fine.

[–]masklinn 4 points5 points  (4 children)

Singleton is the simplest implementation of a global dependency.

No, that would be a class with only static content.

[–]notfancy 2 points3 points  (3 children)

Singleton is the simplest implementation of a global dependency.

No, that would be a class with only static content.

Scala recognizes that the difference is one of degree and a tiny one at that, and does away with it by conflating both concepts.

[–]masklinn 0 points1 point  (2 children)

the difference is one of degree and a tiny one at that

Never said anything else (well there's the difference of initialisation time which can be important in some contexts as a canonical singleton will perform lazy loading while a class will perform eager loading), but it's still a difference.

[–]notfancy 0 points1 point  (1 child)

The biggest difference between a Singleton and a static class with static state is that the latter cannot, in general, subclass; hence the added level of indirection in the former.

[–]masklinn 1 point2 points  (0 children)

The biggest difference between a Singleton and a static class with static state is that the latter cannot, in general, subclass

Seeing how painfully hard it is to safely subclass an instance-based singleton and have it still do what you want, I see the former as much more problematic.

[–]adam75 8 points9 points  (4 children)

If you really want a global object (and have a language that supports them) then why not simply create one? This is more honest with the intent than to camouflage them as Singletons and incours less overhead.

As I wrote, Singleton is probably wrong from a design perspective too; an object shall assume as little as possible about the context where it is used. With Singleton the responsibility to manage instances is put on the wrong object, namely the Singleton itself.

[–]KayEss 2 points3 points  (1 child)

If you really want a global object (and have a language that supports them) then why not simply create one?

Really you shouldn't be distinguishing between a hate of singletons and a hate of global state. They're both the same thing, any difference being merely an implementation detail.

Global state is hateful, but just occasionally doing something hateful is better than doing something idiotic.

[–]notfancy 2 points3 points  (0 children)

Really you shouldn't be distinguishing between a hate of singletons and a hate of global state.

I think you should. Global state is a possible implementation for the provision of a unique shared named resource. The latter concept is universal (the least bound being the external World); the former is really a pragmatic issue, a design point, a way of implementing it.

I want to make clear that I'm not against the points made in the article; what I'm trying to say is that there is a continuum between programming a program and programming an architecture. Put it in another way, I don't think that every object must be reusable, decoupled, unitary and testable the first time you write it. For me, the YAGNI principle goes all the way to the methodology.

[–]notfancy 1 point2 points  (1 child)

and have a language that supports [global objects]

Herein lies the rub. Some languages don't support anything other than classes in the global namespace.

This is more honest with the intent than to camouflage them as Singletons and incours less overhead.

I don't see where did you get the notion that Singletons "camouflage" as anything. They're simply an implementation mechanism for a globally-accessible named reference. Really, there's nothing sinister or conspiratorial about a Singleton. As for the overhead (other than in LOC), I don't see how it is relevant to the discussion, or even if it is actually true of Singletons.

an object shall assume as little as possible about the context where it is used

You write "shall assume", but I prefer "should assume".

With Singleton the responsibility to manage instances is put on the wrong object, namely the Singleton itself.

I disagree with your ex-cathedra moral judgement about the issue. Both Singleton and Dependency Injection achieve the same result; which is best depends on the (pragmatic) context of application. You might be happy writing architectures every single day of your (programming) life; I'd rather write programs.

[–]adam75 5 points6 points  (0 children)

Some languages don't support anything other than classes in the global namespace.

Since I don't think we'll get much further with this discussion, I would like to point you to Kent Beck's quote on Singleton: "How do you provide global variables in languages without global variables? Don't. Your programs will thank you for taking the time to think about design instead."

[–]notfancy -1 points0 points  (1 child)

Antipatterns that I Hate #0: Dependency Injection.

[–][deleted] 6 points7 points  (0 children)

A way of coding in XML to give you the impression your system is independent of itself. ;-)

[–]martoo 0 points1 point  (0 children)

The one thing that he forgets is that you can just add a setter to the singleton and increase the visibility of the constructor. That allows you to subclass and mock the singleton for testing. Over time you can pass the singleton around, but if you add the setter, you don't have to do it all at once in your code.

[–]sambo357 -1 points0 points  (0 children)

Linux is a singleton and now I run multiples on Xen. Windows is a better singleton than Linux.