Matt wrote:
I'm rather new to C++ and have a question about globals.
A global object is often called a Singleton.
Here's Mike Feathers ragging on why even high-level encapsulated
globals are bad:
> P> Leave it alone. It wasn't hurting anything.
>
> "Nobody knows the trouble I've seen."
I get the sense from Phlip's comment in a thread on TDD that he
doesn't mind Singletons, whereas we appear to revile them. (I typed
"relive" the first time, and that's a perfect Freudian slip.)
I usually create a Factory class, have it serve up the Singleton,
change everything to use the Factory class, try to minimize the number of
invocations of new SingletonFactory(), then dump turn the Singleton
in a normal Object. ("I'm a real boy!")
P> I revile 'if' statements.
P> The OP appeared to identify the trouble "singleton", not the
trouble "cruft
P> caused by a singleton".
That was just shorthand. Mike Hill has seen an incredible number of
systems, doubtless with an incredible number of reasons to dislike
singletons.
P> Where's the cruft the singleton caused?
Not all singletons are terrible. In the most benign cases, you have a
singleton without mutable state, one that you can send messages to
over and over again without getting different answers or affecting the
state of the system via side effects. In those cases, the bad thing
is really the concrete dependency on the singleton. Because it is
concrete, you must have the singleton available when you are testing.
In some systems, this is a serious link-time dependency. In others,
where the singleton does substantial work, it's a serious running time
issue when you are testing.
The worse ones are singletons that house mutable state. These
singleton objects create singleton systems. When you use the
singleton, you are saying that the code that uses it is part of one
and only one system. You can't take the "using" code and create an
other instance of it that will run on the same VM or machine, run it
and expect the same results. You've taken any hope that you might
have of internally reusing those chasses and shot it in the foot.
There are teams who don't practice enough internal reuse (i.e.,
duplication removal) to care about that, so the other time that the
"singleton system effect" hits them is when they want to write tests
for a piece of code. At that point, they notice that they have a
singleton system. Why? When we test, we want each test to run in its
own little world, to be its own system. With a mutable singleton, you
are just stuck with the world that it defines, unless you do something
like use a static setter.
Looking for cruft? Look in test setups.. you have to remember which
singletons to set instances on. If you forget, you could be silently
leaking state from test to test. If you are writing tests to
characterize the behavior of the system so you can refactor, you may
not even know about the state leaks. Silent error.
I try not to rail too hard about singletons. Like "if"s they are fine
in moderation :-) But, as a guy who goes around and helps people get
chunks of code under test, I see more than my share of trouble caused
by them.
Michael Feathers
www.objectmentor.com