views:

206

answers:

3

I'm working on a Firefox extension where I'll want to keep multiple windows in sync with the same information. The toolbar queries a remote server for info periodically, based on when the window was opened. Because Firefox windows are all separately self-contained environments, each with their own toolbar running separate code I thought I'd use a singleton here. There's really no need for multiple requests, there can be one request for each of the windows, the problem though is that there is no global master scope over-lording it over the multiple windows context, there are only windows contexts. I thought I'd create a factory class that checks to see if one of the windows already has an instance of my notification class running and if so uses that same instance to get updates.

It seems like a legitimate use of a singleton, but I keep reading about how they're evil beasts. Is this an ok use?

+3  A: 

There's nothing inherently wrong with a singleton, per se. The problem lies in how it can be (ab)used: it's essentially a fancy way to have globals. A singleton just lets you have a level of indirection that self-contains most of that data. Sometimes, though, this pattern is the only way you can solve certain problems. In that case, it's perfectly fine. However, if you can think of another way that uses maybe only a little bit more code/memory/performance-hit to accomplish, I'd go with that if I could. Otherwise, there's really nothing wrong with using a singleton, as long as you're aware of what you're getting into.

Robert P
Well, the whole extension is a global scope. So either he litters the global scope with a bunch of crap, or he sticks it all in one object, and litters the global scope with that one object (plus an onload to bootstrap it). I did the latter.
tpdi
Well, the whole extension is at global scope. It's just an additional var or vars on the window. So either he litters the global scope with a bunch of crap, or he sticks it all in one object, and litters the global scope with that one object (plus an onload to bootstrap it). I did the latter.
tpdi
Crap, I can't delete my first comment.
tpdi
+2  A: 

Singletons themselves are not evil. It's their abuse that is... (You can usually get away with using DI container to have your instance "singletoned" which makes this pattern rather less recomended).

I don't have any experience in the area you describe. However singleton seems to me like reasonable option.

Rashack
+2  A: 

The problem is that each Firefox window is an entirely separate process as far as Javascript is concerned.

So yeah, it'll work, but only if you conditionally create the singleton. If it's just unconditionally created at global scope (in my my case, as a member of my top-level extension object), it's going to be in all windows.

The other problem you're going to have is that windows take a while to start and run javascript, and you don't have anything like synchronization. It's entirely possible that window 1 checks to see if window 2 has created the singleton, sees it hasn't, window 2 check window 1, sees it hasn't, and then both create their own singleton.

I speak from experience: I wrote a Firefox extension that does something very much like what you want to do: only one window is supposed to check the remote server (and all other windows need to be informed when any one window closes).

(In mine, each window on start-up queries all other windows to find the "master" window.)

The cleaner way around this is to create a service, just like the ones the browser exposes to javascript; but that requires coding in in C, not javascript, and makes installing teh extension cross platform more of a pain.

tpdi
I'll figure maybe I'll check once and a while to see if there are multiple instances and if so remove all but one? Hrm
apphacker
Honestly, I wouldn't even bother, unless it's super big. Remember, the memory consumed by each window's copy of the extension is the size of the code plus whatever objects the code creates. If you end up writing lots of code to remove a small object, you're already losing.
tpdi