On Wed, 25 Jul 2007 12:56:53 -0700, Bob Johnson <A@B.comwrote:
Just wondering the extent to which some of you are implementing classes
as
Singletons. I'm working on a brand new project and, early on, identified
some obvious candidates. By "obvoius candidates" I mean classes for which
terrible problems would clearly arise if more than one instance were to
exist. But as I'm getting into the design of this new solution, I'm
realizing that a large percentage of the classes _could be_ implemented
as
Singletons. These are classes for which there is no reasonable
expectation
to ever need more than one instance at a time.
I use it when it's appropriate, where "appropriate" is defined by my own
fickle criteria. :)
I have to say, the decision pretty much _never_ comes down to a question
of whether "terrible problems would clearly arise if more than one
instance were to exist". By that I mean that if that was the case, the
singleton pattern was already suggested earlier by some other design
criteria.
In particular, to me the question of whether to use the singleton or not
is whether I'm dealing with a class that will represent multiple
instances, each with their own state, or I'm dealing with a class that
naturally lends itself to being a singleton.
The decision flow typically just has a couple of questions: is this class
naturally a singleton? and is it worth bothering to make it a singleton?
If something terrible might happen when more than one instance exists,
then the answer to the first question is already "yes" and I never get as
far as considering what terrible things might happen.
Of course, not all singleton classes would actually cause problems being
multiply instanced...they'd just be wasteful. So that's where the second
question comes in. There's a certain amount of hassle involved in making
a class a singleton. Not much, of course, but it does create at least a
little complication. So for a really simple class, I would just not
bother.
For example, something that came up for me recently was the need to
implement the IComparer interface. I wanted a brand new class for this,
as I didn't have a class already that naturally lent itself to the task.
I mean, I could've just implemented the interface in my main form class,
for all the Sort() method cared, but it wasn't a perfect fit in that
particular case, so I decided against that. But the new class I made
didn't have _any_ member fields. All it did was implement the one
required method, IComparer.Compare().
At the same time, it seemed silly to instantiate one of these each time I
wanted to compare something, especially when I wanted to do the comparison
in situations where I wasn't actually using the IComparer interface (that
is, sometimes I needed to pass an IComparer to something, like Sort(), but
in other cases it was my own code doing the comparison and so I didn't
need to require an IComparer instance). I _could_ have addressed all of
this by making the class a singleton.
But I didn't. I just made a static comparison method, which was callable
by any arbitrary code (i.e. my own code that was aware of the class
itself), and which was called by the instance method IComparer.Compare().
That way, I didn't even need an instance in most cases. When I did need
an instance, I went ahead and just made one, not worrying about whether
having multiple instances around would be a problem, even though they
would be redundant.
The only theoretical problem would have been memory consumption, which
isn't much of an issue when your class contains no member fields and when
you have single-threaded coded in which the instance exists for only brief
periods of time. In fact, in some respects this is better than using a
singleton, because the class instance exists only when it's actually
needed, and will be automatically be released if the memory needs to be
reclaimed when it's not in use. Yes, I gather an alternative solution
involves using a WeakReference with the singleton pattern, but that's even
more complicated, and one of the highest priority design criteria I have
is to keep the code simple.
So, in spite of all of the words, I think the sum-up is what I wrote at
the outset. If a class is a naturally a singleton, _and_ it is simpler to
implement it as a singleton than to work around its singleton nature some
other way, then I implement it as a singleton. Otherwise I don't.
Pete