<<<
Still, the typical usage pattern is to store the instance into a local
variable and reference it that way, rather than typing
"SubclassSingleton.Instance" over and over again. Conversely, if you are
only using the method from the singleton once in a given block of code,
who cares how long it is, especially given that the IDE makes it nearly
the same in terms of typing as if it were simply a static method.
In any case, the question of typing has very little to do with the
question of OO design. It's not a good idea to try to contort OO design
just so you can avoid some typing. And generally, since OO design is
about code reuse, any typing you might save, you do so only in the
short-run, spending more time typing just to do the contortions you desire.
Penny-wise, pound-foolish, some might say.

I'm not talking about the inconvenience of extra typing.
I'm talking about readability.
I'm sure you've worked on large projects with many developers who ( despite
team-level efforts to establish standards & practices ) all write code in a
slightly different style.
A couple common patterns in team-developed projects that I find lend to poor
readability are :
1. too many lines of code that are too long to fit within a common window
width ( e.g. VS settings out of the box , 19" monitor )
If too-long code-lines are not split into multiple-lines, it is a huge pain
to constantly be scrolling to the right.
If too-long code-lines are meant to be multi-lined , it becomes an
enforcement problem ( i.e. not all devs check-in clean code ) , and there
are definitely are serious readability issues with some multi-lined lines of
code ( i.e. there are good ways to go about splitting the code ,and there
are very bad ways to go it -- trust me I've seen it )
The too-long code-lines problem is a direct outgrowth of the modern OO
standard practice first advanced by Gosling ( I think ) towards giving
meaningful "plain English" names to entities. Everything in this world is a
blance , pro/con, yin/yang, and Gosling's propagation of a coding pattern of
devising "plain English" names is not without negatives.
2. use of obscure acronyms
For example , in the project I'm working on now , sure , I could do this :
public Method1()
{
MarketDataDatabase mdDb = MarketDataDatabaseSingleton.Instance;
ApplicationDatabase appDb = ApplicationDatabaseSingleton.Instance;
PositionKeeperDatabase pkDb = PositionKeeperDatabaseSingleton.Instance;
// 100s of lines of code later ...
// line number 678
LongEntityName longEntityInstanceName =
pkDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> , etc. );
AnotherLongEntityName anotherLongEntityInstanceName =
mdDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> , etc. );
// etc.
}
The problem here is that someone new to the project might be resolving a bug
that's known to occur on line 678 , and they look at "mdDb" and "pkDb" and
think "what's that ?"
Sure, right-click "Go To Definition" ... but my point is that all these
niggling memory-joggers and jumping-around to gain understanding **can and
do** add-up to brain twisting inertia in a gargantuan mutli-dev project with
100s or even 1000s of classes where oftentimes even the original author of a
given section of code gets badly confused coming back months later after
numerous bug-fixes and extentions/additions/tweaks by others.
Plus , what if some other dev on the project writes similar code in some
other method like this :
public Method2()
{
MarketDataDatabase market = MarketDataDatabaseSingleton.Instance;
ApplicationDatabase app = ApplicationDatabaseSingleton.Instance;
PositionKeeperDatabase position =
PositionKeeperDatabaseSingleton.Instance;
// etc.
}
Now we've lost any sort of standardization in naming of the local instance
vars , and the confusion multiplies.
What I look to do in designing class libs is give people fewer chances to
expand the "application nomenclature" in obscure , non-congruent ,
personalized fashion.
Peter Duniho said:
I don't see any reason why a language could not be designed where static
classes can inherit static classes.
One _can_ design a programming language to be and do just about anything
the designer wants.
That's not really the point.
[...]
As far as singletons, I do see disadvantages. There are threading
issues if not designed properly,
Red herring. If there are threading issues, there are threading issues
with or without the singleton and you need to solve them either way. If
you're simply talking about the instance getter itself, well...that's
something you only have to do once, and there are numerous examples you
can follow to make sure you do it right (including simply letting the
run-time handle it for you by using a static initializer for the instance
variable).
there is a slight performance hit always having to obtain the instance,
Completely untrue. The getter will be inlined, and will be barely
different than whatever dereferencing was required internally in a static
method to accomplish your goal. There is no measurable performance
difference. That would be true with _any_ singleton vs. static class
design, but in your case with the databases involved, it's especially
true. The cost of accessing the database will completely dominate.
and the usage syntax is wordy ( if , like me , you like to give
meaningful names to your classes ) .
If you insist, you can always write static methods on the containing class
that simply delegate to the instance. Depending on the rest of the
design, you might even be able to take advantage of extension methods, and
use that syntax with an pre-existing object you know you'll always be
using with the static methods.
Still, the typical usage pattern is to store the instance into a local
variable and reference it that way, rather than typing
"SubclassSingleton.Instance" over and over again. Conversely, if you are
only using the method from the singleton once in a given block of code,
who cares how long it is, especially given that the IDE makes it nearly
the same in terms of typing as if it were simply a static method.
In any case, the question of typing has very little to do with the
question of OO design. It's not a good idea to try to contort OO design
just so you can avoid some typing. And generally, since OO design is
about code reuse, any typing you might save, you do so only in the
short-run, spending more time typing just to do the contortions you
desire.
Penny-wise, pound-foolish, some might say.
Pete