Hacker News new | ask | show | jobs
by demallien 5534 days ago
Well, two points come to mind:

1) Singletons do make sense when they represent a true physical singleton - for example, you only want one piece of code drawing directly to the screen, the Window Manager, which should indeed be a singleton.

2) Most of your problems stem from the us of GetInstance() not from the use of the Singleton pattern in and of itself. For example, without GetInstance(), the other way to get a reference to the Singleton object is to pass it in to the object that is going to use it. This indicates the dependency in the client class's interface, and also makes mocking out the Singleton for test purposes a real possibility.

6 comments

for example, you only want one piece of code drawing directly to the screen

therein lies the problem: most of us are, in general, terrible at predicting the future. By the time I notice I now want more than one piece of code drawing directly to the screen, my code is already full of wrong assumptions.

One way of easing this is -- as you point out -- to make dependencies explicit and abandon GetInstance. Better yet if realizing that, as a design guideline, "needing only one of something" trumps "something being a singleton" any day. This is the kind of future-proofing that generally doesn't hurt the schedule.

""Singletons do make sense when they represent a true physical singleton - for example, you only want one piece of code drawing directly to the screen, the Window Manager, which should indeed be a singleton.""

That's a false dichotomy. Trying to understand the world as global or local data doesn't make sense; It's contextual. What may be global to you may be local to the next guy and vice versa.

What does make sense, is for a programmer to make a judgement call as to whether something could meaningfully be considered global for the particular case he's working on.

I used to like the concept of dependency injection, but I have come to find it mostly just adds noise. If you use a dynamic language anyway. I don't know about statically, compiled languages, since I don't do much work in those.

"That's a false dichotomy. Trying to understand the world as global or local data doesn't make sense; It's contextual. What may be global to you may be local to the next guy and vice versa."

Err, firstly I didn't present a dichotomy,false or otherwise. http://en.wikipedia.org/wiki/Dichotomy

Secondly, I have no idea what you're talking about. I'm not talking about whether data is global or local, I'm saying that when you have a single physical asset, it doesn't make sense (and sometimes is even flat out wrong) to have more than one object talking to it. You will get into a big mess if you have two NetworkManagers trying to set up the one ethernet port at the same time, as a simple example. Whether that representation is local or global is orthogonal to the problem.

Using the labels "global" and "local" as distinct categories is the dichotomy I referred to. I see them relative values, not absolutes. You can't have something be "global" or "local" - Only "More global" or "More local". I understood that you operate with categories here - Maybe I'm mistaken?

Certainly, for a given program it may (or may not) make sense to have a restriction which prevents one type of resource to be assigned more than once. My point being that there is no need to treat this restriction as "special" somehow.

Yes, but I didn't use the labels "global" and "local", so why on earth are you still going on about them as though I had?
Question regarding the injection. I've found that while injecting dependencies is good, I still prefer the brevity of not having to declare the common case. Basically, I allow an injection to take place, but make it optional, and if one isn't passed, I use the common case, which in effect makes a call to a getInstance.

Any thoughts on that?

Well, that is a workable solution, but then, I'm sure you're already aware of that, seeing as you use it already ;) Personally I prefer having the object appear in the published interface, it helps highlight the existence of a dependency, but your way doesn't seem horrible either. I suspect that it depends a lot the language you're using. I'm a C programmer, and optional parameters are quite verbose in C, so I would never choose your solution, but in Ruby or Javascript your solution could be quite clean.
My big concern is always implementing a solution and not seeing an otherwise obvious problem. Hence the question. =)

As a PHP guy, setting up optional params are easy, so I like the solution.

I have done that as well. That is one of the strategies we have used on my team @ work. One specific case was where we were basically being integrated into a much larger, older component and they had their own way of doing things. Dependency injection wasn't an option. So we did a default for that case and exposed the dependencies so that we could mock them out in our tests.
You are, of course, correct, but I am yet to come across a single production system that uses singleton in that manner that isn't driven by Spring or some other IoC container.

Fact of the matter is: canonical implementation of singleton is with getInstance(), so when people rail against Singleton, the getInstance() implementation is implied.

"true physical singleton"s have a way of becoming not true. Here's a couple of people who have run multiple window managers at the same time: http://ubuntuforums.org/showthread.php?t=212731 http://duopetalflower.blogspot.com/2010/01/running-multiple-... .
My personal approach is singletons make sense only when:

1. There should be one instance of the data and

2. The data needs to be lazily initialized.

Otherwise, you might as well drop the facade and use globals.