I have moved to naming global singletons with a The* prefix
twitter.com
twitter.com
I did find when participating on a standards group within our shop that you cannot have any ambiguity when it comes to naming conventions. When there is we end up with some designated to lead and force all decisions to that person, it becomes amazing how many different ways developers can say the same thing.
"There are only two hard problems in Computer Science:
cache invalidation and naming things."
-- Phil KarltonThen unit testing becomes feasible again, without having to hack around that Class X is using the "ConnectionManager" to connect to the database behind your back.
My reply was along the lines of "when was the last time you accidentally wrote two for loops when you wanted only one? If you don't want more than one ConnectionManagers then don't create more than one"
In my opinion its very rare that you need an object that is both globally accessible and you must not have more than one.
Some (perhaps most) people who use singletons use them inappropriately. That does not imply that there is no situation for which using one would be appropriate.
The pattern is not to blame, but the close coupling, global state, multiple responsibility, and dependency hiding that are enabled by it. They're perfectly fine as resource managers or for immutable references.
Also, premature optimization is an anti-pattern. The advantage of singleton is that it is super easy to set up, and get to working code, then refactor it out immediately afterward.
If removing it does not improve the code, it must belong there, right? That said, it's pretty easy to improve the code by removing it.
If I were to compile a top 10 list of terrible refactoring projects I've worked on, ALL of them would be on code that had stalled out due to a "singleton" global variable code-complexity ceiling.
Anti-singleton is a holy war because the people who produce such shockingly crap singleton-riddled code are externalizing enormous and soul-crushing costs onto both customers and future maintainers.
I'd caution against inverting the conditional probability of writes singletons given unskilled programmer into probability of unskilled programmer given writes singletons. It's a fallacious operation.
You can't eliminate bad code by eliminating singletons. You can only do it by turning unskilled programmers into skilled programmers. "Don't use singletons" is fine advice for a novice, but it would be better to teach the principles that underlie that advice and use Socratic questioning to make them realize that MOST uses of singleton violate one or more of those principles.
Take the self-referencing problem: let's say we have a logger singleton (pretty simple, what could possibly go wrong?) And let's say that the logger singleton invokes particular code during its initialization, such as the file I/O code that is also our own and that uses... guess what? a logger! Thus, when the logger class initializes, it will either try to log using an uninitialized object or invoke the initialization recursively depending on whether the singleton is lazy or not. A beginner is normally not aware of this problem when they are writing their singleton class. Another problem is the initialization order: what is initialized first - the logger singleton or the I/O singleton? Turns out, we just have to use lazy initialization. Then the multithreading comes on the scene. So you have to make a thread safe lazy singleton. But that implies additional cost on every call for the singleton.
I don't know... Singletons are a mess.
Then the word "manager" became unfashionable.
Pick any, or invent your own.
AudioDictator, StreamingDictator, VoipDictator...
The actor/CSP model makes each device a separate process, which can be hooked together with processing nodes works wonderfully.
You call it TheSecondCamera, duh.
For programmers who have not been through the process of evolving game design and engine requirements getting the balance of flexibility and productivity is tricky. Hoping the fact JC uses singletons does encourage them to be sprinkled more liberally than they already are!
It's things like this that turn a 'sure, we can make this game split-screen' into 'you didnt tell us you wanted split screen, that's gonna take a while'.
For example, how would you go about implementing a connection pool without a singleton? Even if you pass it around everywhere, it's still a singleton, just explicit instead of implicit.
To your example of the connection pool, there is absolutely no reason that this has to be a singleton. You could have N connection pools, each with their own pool of connections, just as you could have N thread pools, or N memory heaps. This is not only possible but sometimes preferable, if different subcomponents need resource isolation (so that some connection-hungry component can't starve a component that needs reasonable responsiveness for the interface, for example).
Further, most of your code shouldn't even care about the connection pool. That's a level of coupling you generally do not need. Most code should care only about an actual connection, which could be passed in. Taking a direct dependency on the connection pool when not necessary increases pointless coupling and makes changes more expensive.
(Don't get me wrong, they are necessary)