## Monostates vs. Singletons (Was: Re: [XP] Singletons == Global s?)

Expand Messages
• ... lot. ;-) ... Monty Python and the Holy Grail. And I believe the quote is, On second thought, let s not go to Camelot. Tis a silly place. -Matthew
Message 1 of 27 , Apr 2, 2001
--- In extremeprogramming@y..., Ryan King <rking@c...> wrote:
> > "On second thought, let's not go to Camelot. They are a silly
lot." ;-)
> You're my next victim -- Where does that Camelot thing come from?

Monty Python and the Holy Grail. And I believe the quote is, "On
second thought, let's not go to Camelot. 'Tis a silly place."

-Matthew
azami@...
• Thanks, I haven t seen that movie lately and I m starting to forget a few lines. - George I saw a doctor, once. E didn t see me. I was iding. From:
Message 2 of 27 , Apr 2, 2001
Thanks, I haven't seen that movie lately and I'm starting to forget
a few lines.

- George

"I saw a doctor, once. 'E didn't see me. I was 'iding."

From: azami@... [mailto:azami@...]
> --- In extremeprogramming@y..., Ryan King <rking@c...> wrote:
> > > "On second thought, let's not go to Camelot. They are a silly
> lot." ;-)
> > You're my next victim -- Where does that Camelot thing come from?
>
> Monty Python and the Holy Grail. And I believe the quote is, "On
> second thought, let's not go to Camelot. 'Tis a silly place."
• ... I don t think that getInstance implies a singleton or not. ... eh??? ... it ... OK, putting the log prefix each time isn t a great solution. (I ll blame
Message 3 of 27 , Apr 2, 2001
> From: Ryan King [mailto:rking@...]

> Wwhat I was getting at was that the member "SomeSingleton::instance_"
> seems to me to be a subpart of "class SomeSingleton".
>
> On the other hand, it is true that you could re-work the innards of "class
> SomeSingleton" and "SomeSingleton::getInstance()" so that it can have
> instance data, proving that the structure isn't known by the users of the
> class.
>
> I have two problems with that solution, though:
>
> 1) Now the code is definitely lying. "getInstance()" means
> "getTheInstance()", but we're redefining it to mean "getAnInstance()".
> What does the operator "new" mean but "getAnInstance()"? Why not use
> it instead, even if there is incidentally only one?

I don't think that getInstance implies a singleton or not.

> 2) On the practical side, it requires more thought and code to do the
> necessary rewrite (as compared to a Monostate).

eh???

> > Well, I wouldn't think of putting such state into the Logger. I treat
it
> > as a facility that all the code can use, but none of them own it.
>
> I would at least think of it, because I the following is redundant:
>
> > String logPrefix = "foo: ";
> > log(logPrefix, [...]
> > log(logPrefix, [...]
> > log(logPrefix, [...]
>
> The point here is: If you have an object that is a hybrid between class
> data and instance data you will have a more difficult time if you're
> starting with the Singleton pattern. I've always thought of static data
> as smell, and it seems that the difficulty involved in creating instance
> data discourages removal of this smell.

OK, putting the log prefix each time isn't a great solution. (I'll blame
it on my invisible pair.)

public class Logger {
private static Logger singleton = new Logger();
private Logger() {
}
public void log(String message) {
System.out.println(message);
}
public static Logger getInstance() {
return singleton;
}
}

Now, we want to add prefixes:

public class Logger {
private static final String emptyString = "";
private String prefix;
private static Map loggers = new HashMap();
private Logger(String prefix) {
loggers.put(prefix, this);
}
public void log(String message) {
System.out.println(prefix+message);
}
public static Logger getInstance() {
return getInstance(emptyString);
}
public static Logger getInstance(String prefix) {
Logger instance;
if (loggers.containsKey(prefix)) {
instance = (Logger)loggers.get(prefix);
} else {
instance = new Logger(prefix);
}
return instance;
}
}

Does this smell better?

- George

P.S. Thanks for this discussion. Currently I don't have anyone suitable
for
discussing code smells. Too many people here haven't developed a nose or
think
that "if it ain't broke, don't fix it." I need the feedback.
• ... Color me clueless. Why not just add a method public static void Log(String message) { getInstance().log( message ); } and call it with Logger.Log(
Message 4 of 27 , Apr 2, 2001
On Mon, 2 Apr 2001, Dinwiddie, George wrote:

> public class Logger {
> private static Logger singleton = new Logger();
> private Logger() {
> }
> public void log(String message) {
> System.out.println(message);
> }
> public static Logger getInstance() {
> return singleton;
> }
> }

Color me clueless. Why not just add a method

public static void Log(String message) {
getInstance().log( message );
}

and call it with Logger.Log( "lalala" );

The getInstance/log combo doesn't tell you anything more about what state
the logger maintains or what the intent is of keeping an instance of it.

I fail to see how code which does logging via Logger.getInstance().log()
could remain unmodified if you added prefixes or other semantics to the
logger. Since you will have to refactor client code anyway might as well
choose the simplest, prettiest option - which to me is Logger.Log().

- Eric B.

--
"Actually I'm a Lumberjack, and I'm okay!"
• Good point. I thought of that possibility, but then thought that I d be more likely to collapse them into a single class, as shown, at least until I needed to
Message 5 of 27 , Apr 2, 2001
Good point. I thought of that possibility, but then thought that
I'd be more likely to collapse them into a single class, as shown,
at least until I needed to differentiate them. To me, it was an
easier refactoring.

I notice that your PrefixedLogger is quite different from your
Logger.
- It doesn't use a factory to create it.
- It's not a derived class, so there's more work to convert
calling code from Logger to PrefixedLogger.

Since we don't have any actual client code, maybe this is ok.
It kinda nags at me, though.

- George

-----Original Message-----
From: Rex_Jolliff@... [mailto:Rex_Jolliff@...]

Your solution seems to be doing two things in one, how about:

public class Logger {
private static Logger singleton = new Logger();
private Logger() {
}
public void log(String message) {
System.out.println(message);
}
public static Logger getInstance() {
return singleton;
}
}

public class PrefixedLogger {
String Prefix;

public PrefixedLogger (String aPrefix) {
this.Prefix = aPrefix;
}
public void log (String aMessage) {
Logger.getInstance ().log (this.Prefix + aMessage);
}
}

"Dinwiddie, George" <George.Dinwiddie@...> on 04/02/2001 11:21:35
AM

To: "'extremeprogramming@yahoogroups.com'"
<extremeprogramming@yahoogroups.com>

cc: (bcc: Rex Jolliff/YM/RWDOE)

Subject: RE: Monostates vs. Singletons (Was: Re: [XP]
Singletons == Global s?)

Federal Record Status Not
Determined

> From: Ryan King [mailto:rking@...]

> Wwhat I was getting at was that the member "SomeSingleton::instance_"
> seems to me to be a subpart of "class SomeSingleton".
>
> On the other hand, it is true that you could re-work the innards of "class
> SomeSingleton" and "SomeSingleton::getInstance()" so that it can have
> instance data, proving that the structure isn't known by the users of the
> class.
>
> I have two problems with that solution, though:
>
> 1) Now the code is definitely lying. "getInstance()" means
> "getTheInstance()", but we're redefining it to mean "getAnInstance()".
> What does the operator "new" mean but "getAnInstance()"? Why not use
> it instead, even if there is incidentally only one?

I don't think that getInstance implies a singleton or not.

> 2) On the practical side, it requires more thought and code to do the
> necessary rewrite (as compared to a Monostate).

eh???

> > Well, I wouldn't think of putting such state into the Logger. I treat
it
> > as a facility that all the code can use, but none of them own it.
>
> I would at least think of it, because I the following is redundant:
>
> > String logPrefix = "foo: ";
> > log(logPrefix, [...]
> > log(logPrefix, [...]
> > log(logPrefix, [...]
>
> The point here is: If you have an object that is a hybrid between class
> data and instance data you will have a more difficult time if you're
> starting with the Singleton pattern. I've always thought of static data
> as smell, and it seems that the difficulty involved in creating instance
> data discourages removal of this smell.

OK, putting the log prefix each time isn't a great solution. (I'll blame
it on my invisible pair.)

public class Logger {
private static Logger singleton = new Logger();
private Logger() {
}
public void log(String message) {
System.out.println(message);
}
public static Logger getInstance() {
return singleton;
}
}

Now, we want to add prefixes:

public class Logger {
private static final String emptyString = "";
private String prefix;
private static Map loggers = new HashMap();
private Logger(String prefix) {
loggers.put(prefix, this);
}
public void log(String message) {
System.out.println(prefix+message);
}
public static Logger getInstance() {
return getInstance(emptyString);
}
public static Logger getInstance(String prefix) {
Logger instance;
if (loggers.containsKey(prefix)) {
instance = (Logger)loggers.get(prefix);
} else {
instance = new Logger(prefix);
}
return instance;
}
}

Does this smell better?

- George

P.S. Thanks for this discussion. Currently I don't have anyone suitable
for
discussing code smells. Too many people here haven't developed a nose or
think
that "if it ain't broke, don't fix it." I need the feedback.

To Post a message, send it to: extremeprogramming@...

To Unsubscribe, send a blank message to:
extremeprogramming-unsubscribe@...

Don't miss XP UNIVERSE, the first US conference on XP and Agile Methods.
Early
registration discounts until April 10, 2001. www.xpuniverse.com for details
and
registration.

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/

To Post a message, send it to: extremeprogramming@...

To Unsubscribe, send a blank message to:
extremeprogramming-unsubscribe@...

Don't miss XP UNIVERSE, the first US conference on XP and Agile Methods.
Early registration discounts until April 10, 2001. www.xpuniverse.com for
details and registration.

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
• As my example showed, you *don t* have to change the client code if they don t require a prefix. As for your suggestion, if you re going to go that route, why
Message 6 of 27 , Apr 2, 2001
As my example showed, you *don't* have to change the
client code if they don't require a prefix.

As for your suggestion, if you're going to go that
route, why not just condense it to

public class Logger {
public static void Log(String message) {
System.out.println(message);
}
}

In fact, the above is frequently my starting point in a program.
It usually doesn't last very long, though, before I rip it out
and replace it with something else. Maybe that's just prejudice
on my part, however.

Does a static method have more or less smell than a singleton
accessed via a static factory method?

- George

-----Original Message-----
From: Eric Bennett [mailto:ericb@...]

On Mon, 2 Apr 2001, Dinwiddie, George wrote:

> public class Logger {
> private static Logger singleton = new Logger();
> private Logger() {
> }
> public void log(String message) {
> System.out.println(message);
> }
> public static Logger getInstance() {
> return singleton;
> }
> }

Color me clueless. Why not just add a method

public static void Log(String message) {
getInstance().log( message );
}

and call it with Logger.Log( "lalala" );

The getInstance/log combo doesn't tell you anything more about what state
the logger maintains or what the intent is of keeping an instance of it.

I fail to see how code which does logging via Logger.getInstance().log()
could remain unmodified if you added prefixes or other semantics to the
logger. Since you will have to refactor client code anyway might as well
choose the simplest, prettiest option - which to me is Logger.Log().

- Eric B.
• ... blame ... Better, but still not very good. In my opinion. Maybe I d like it better if some of the names were changed - getInstance() by convention
Message 7 of 27 , Apr 2, 2001
--- In extremeprogramming@y..., "Dinwiddie, George"
<George.Dinwiddie@a...> wrote:
> > From: Ryan King [mailto:rking@c...]
> > I would at least think of it, because I the following is
redundant:
> >
> > > String logPrefix = "foo: ";
> > > log(logPrefix, [...]
> > > log(logPrefix, [...]
> > > log(logPrefix, [...]
>
> OK, putting the log prefix each time isn't a great solution. (I'll
blame
> it on my invisible pair.)
>
> ...
> Now, we want to add prefixes:
>
> public class Logger {
> private static final String emptyString = "";
> private String prefix;
> private static Map loggers = new HashMap();
> private Logger(String prefix) {
> loggers.put(prefix, this);
> }
> public void log(String message) {
> System.out.println(prefix+message);
> }
> public static Logger getInstance() {
> return getInstance(emptyString);
> }
> public static Logger getInstance(String prefix) {
> Logger instance;
> if (loggers.containsKey(prefix)) {
> instance = (Logger)loggers.get(prefix);
> } else {
> instance = new Logger(prefix);
> }
> return instance;
> }
> }
>
> Does this smell better?

Better, but still not very good. In my opinion. Maybe I'd like it
better if some of the names were changed - getInstance() by convention
implies singleton. This is only by convention, it doesn't enforce it
in code or anything, and I'd always write code not to care whether the
result of getInstance() is a singleton or not. Also, you'll end up
with (potentially) different log object instances all trying to
operate on the same resource, which could get tricky in a
multi-threaded application. Not unsolvable, just unnecessary. :-)

My idea: Write the logger as a singleton. Write an access class for
the logger (could use the same interface) that is not a singleton and
has state (the prefix).

class PrefixedLogger {
private String prefix;
public String getPrefix() { return prefix; }
public setPrefix(String prefix) { this.prefix = prefix; }

public log(String message) {
Logger.Log(prefix + ": " + message); //See NOTE below
}
}

NOTE: I prefer in some cases to avoid the indirection of
getInstance(), and use static methods instead. It's more work if/when
you need more than one instance, but in the meantime the syntax is
simple and intuitive - just like System.out. If you want proof that
this is simpler, just watch how typical beginning Java programmers
react to all the getInstance() and toolbox stuff!

Reactions?

-Matthew
azami@...
• ... PrefixedLogger is fundamentally different from Logger, though. Logger is a Singleton. PrefixedLogger isn t. (I suggested this solution a week or 2 ago,
Message 8 of 27 , Apr 2, 2001
> -----Original Message-----
> From: Dinwiddie, George [mailto:George.Dinwiddie@...]
> Sent: Monday, April 02, 2001 2:40 PM
> To: 'extremeprogramming@yahoogroups.com'
> Subject: RE: Monostates vs. Singletons (Was: Re: [XP] Singletons ==
> Global s?)
>
>
> Good point. I thought of that possibility, but then thought that
> I'd be more likely to collapse them into a single class, as shown,
> at least until I needed to differentiate them. To me, it was an
> easier refactoring.
>
> I notice that your PrefixedLogger is quite different from your
> Logger.
> - It doesn't use a factory to create it.
> - It's not a derived class, so there's more work to convert
> calling code from Logger to PrefixedLogger.

PrefixedLogger is fundamentally different from Logger, though. Logger is a
Singleton. PrefixedLogger isn't.

(I suggested this solution a week or 2 ago, btw.)
• ... Oh, agreed. I would start with this about 10 seconds before I made System.out a variable so a new stream could be swapped in for testing. ... Less in my
Message 9 of 27 , Apr 2, 2001
On Mon, 2 Apr 2001, Dinwiddie, George wrote:

> As for your suggestion, if you're going to go that
> route, why not just condense it to
>
> public class Logger {
> public static void Log(String message) {
> System.out.println(message);
> }
> }
>
> In fact, the above is frequently my starting point in a program.

"System.out" a variable so a new stream could be swapped in for testing.

> Does a static method have more or less smell than a singleton
> accessed via a static factory method?

Less in my book unless something non-global characterizes the factory.
Maybe I just don't get it yet.

- Eric B.

--
• From: azami@speakeasy.net [mailto:azami@speakeasy.net] ... Well, my experience with the Java run-time-library doesn t suggest that getInstance() implies
Message 10 of 27 , Apr 2, 2001
From: azami@... [mailto:azami@...]
> [snip]Maybe I'd like it
> better if some of the names were changed - getInstance() by convention
> implies singleton. This is only by convention, it doesn't enforce it
> in code or anything, and I'd always write code not to care whether the
> result of getInstance() is a singleton or not.

Well, my experience with the Java run-time-library doesn't suggest that
getInstance() implies singleton. Check out the various flavors of
java.util.Calendar.getInstance, for example. Maybe I'm wrong, but I've
standardized my code to use getInstance() for almost any factory
method. When I first coded singletons in Java, I used getSingleton(),
but quickly decided that my client code didn't care whether or not it
was a singleton. (I think this was about when I first converted a
singleton to a non-singleton.)

> Also, you'll end up
> with (potentially) different log object instances all trying to
> operate on the same resource, which could get tricky in a
> multi-threaded application. Not unsolvable, just unnecessary. :-)

Not so tricky. It's easy to put synchronization inside the Logger
class to make it thread safe.

> My idea: Write the logger as a singleton. Write an access class for
> the logger (could use the same interface) that is not a singleton and
> has state (the prefix).
[code snipped]
> NOTE: I prefer in some cases to avoid the indirection of
> getInstance(), and use static methods instead. It's more work if/when
> you need more than one instance, but in the meantime the syntax is
> simple and intuitive - just like System.out. If you want proof that
> this is simpler, just watch how typical beginning Java programmers
> react to all the getInstance() and toolbox stuff!

Yes, using a static method works. For some reason I tend not to use
that much any more. Somehow that seems more like a global, to me.

In any event, I wouldn't judge which is simpler by the reaction of a
novice programmer. I've seen too many that think sprinkling magic
numbers around the program is simpler.

So, among the options are:
1. using a static method, which implies a global, singleton service,
if not object.
2. using a constructor (which perhaps just initializes a Monostate),
which implies client control over the creation of objects.
3. using a factory method, which implies to me that the client has
no knowledge over whether a new object is being created or one is
being pulled out of a pool (that may only have one element). To others,
such as yourself, this seems to imply a singleton.

Except for the amount of typing, I currently think that #3 is just as
simple and is more general than #1 or #2. I don't use #3 exclusively,
however, and I'm willing to consider arguments for the alternatives.

- George
• From: Eric Hodges [mailto:eric.hodges@mongoosetech.com] ... a ... Does the client care whether it s a singleton, or not? To me, it s not that the client has a
Message 11 of 27 , Apr 2, 2001
From: Eric Hodges [mailto:eric.hodges@...]
> PrefixedLogger is fundamentally different from Logger, though. Logger is
a
> Singleton. PrefixedLogger isn't.

Does the client care whether it's a singleton, or not? To me, it's not that
the client has a desire to do particular types of logging; it's that the
client has a responsibility to the application to log significant
occurrences.

In fact, I don't think I'd ever want the clients of an class to know
whether or not it's a singleton. It's not their business. If they
start making assumptions about that, you might as well use a global.
At least, that's my thinking.

So, I don't think that singleton-or-not makes a fundamental difference. I
think that's an implementation issue that should live inside the class. In
fact, if we're going to start having different flavors of Logger, I think
I'd be tempted to refactor Logger into an interface. I might also remove
the factory method from any class and create a LoggerFactory, instead.

In any event, I think I'm going to end up with a singleton root logging
object, because I want a single point of control for the logging output.
I'll also generally want to merger multiple log streams into one. Perhaps
I'll want to have multiple log streams, but I wouldn't want that to be
under the control of the client code that sends the log messages.

- George
• ... PrefixedLogger *should* be quite different from Logger. PrefixedLogger isn t a Singleton, so it shouldn t be a subclass of a Singleton. PrefixedLogger
Message 12 of 27 , Apr 2, 2001
> -----Original Message-----
> From: Dinwiddie, George [mailto:George.Dinwiddie@...]
> Sent: Monday, April 02, 2001 3:36 PM
> To: 'extremeprogramming@yahoogroups.com'
> Subject: RE: Monostates vs. Singletons (Was: Re: [XP] Singletons ==
> Global s?)
>
>
> From: Eric Hodges [mailto:eric.hodges@...]
> > PrefixedLogger is fundamentally different from Logger, though.
> Logger is
> a
> > Singleton. PrefixedLogger isn't.
>
> Does the client care whether it's a singleton, or not? To me,
> it's not that
> the client has a desire to do particular types of logging; it's that the
> client has a responsibility to the application to log significant
> occurrences.

The client doesn't care. I was responding to this:

> I notice that your PrefixedLogger is quite different from your
> Logger.
> - It doesn't use a factory to create it.
> - It's not a derived class, so there's more work to convert
> calling code from Logger to PrefixedLogger.

PrefixedLogger *should* be quite different from Logger. PrefixedLogger
isn't a Singleton, so it shouldn't be a subclass of a Singleton.
PrefixedLogger doesn't need a factory method, it can use "new".

>
> In fact, I don't think I'd ever want the clients of an class to know
> whether or not it's a singleton. It's not their business. If they
> start making assumptions about that, you might as well use a global.
> At least, that's my thinking.
>
> So, I don't think that singleton-or-not makes a fundamental difference. I
> think that's an implementation issue that should live inside the
> class. In
> fact, if we're going to start having different flavors of Logger, I think
> I'd be tempted to refactor Logger into an interface. I might also remove
> the factory method from any class and create a LoggerFactory, instead.

You shouldn't try to make a non-Singleton subclass of a Singleton. If that
means the clients treat Logger differently from PrefixedLogger, so be it.
• ... convention ... it ... the ... that ... I ve ... My brain wasn t fully in gear before I engaged my fingers. You ve expressed my true thoughts far better
Message 13 of 27 , Apr 2, 2001
--- In extremeprogramming@y..., "Dinwiddie, George"
<George.Dinwiddie@a...> wrote:
>
> From: azami@s... [mailto:azami@s...]
> > [snip]Maybe I'd like it
> > better if some of the names were changed - getInstance() by
convention
> > implies singleton. This is only by convention, it doesn't enforce
it
> > in code or anything, and I'd always write code not to care whether
the
> > result of getInstance() is a singleton or not.
>
> Well, my experience with the Java run-time-library doesn't suggest
that
> getInstance() implies singleton. Check out the various flavors of
> java.util.Calendar.getInstance, for example. Maybe I'm wrong, but
I've
> standardized my code to use getInstance() for almost any factory

My brain wasn't fully in gear before I engaged my fingers. You've
expressed my true thoughts far better than I did. In fact,
getInstance() implies factory to me, and factory implies more than one
instance. After all, if there's only one of a thing what the heck do
you need a factory for? Just use the thing.

> method. When I first coded singletons in Java, I used
getSingleton(),
> but quickly decided that my client code didn't care whether or not
it
> was a singleton. (I think this was about when I first converted a
> singleton to a non-singleton.)

Ideally, the client code should not know whether the object is a
singleton. You could argue that Logger.Log() looks more like a
singleton than Logger.getInstance().Log(), but

1 - you _can_ introduce instances without changing that interface if
you need to
2 - I think the result is simpler, and until you need more complexity
it's worth it.

> > Also, you'll end up
> > with (potentially) different log object instances all trying to
> > operate on the same resource, which could get tricky in a
> > multi-threaded application. Not unsolvable, just unnecessary. :-)
>
> Not so tricky. It's easy to put synchronization inside the Logger
> class to make it thread safe.

You need class-level synchronization. The most intuitive ways of
synchronizing synchronize on instances. So, two instances could try
to simultaneously access the same resource. You have to remember to
protect the resource, not the Logger objects. But since the Logger is
conceptually representative of the resource, this will be easily
missed...

> Yes, using a static method works. For some reason I tend not to use
> that much any more. Somehow that seems more like a global, to me.

I think the concept of a "global service" is good for services that
are global. It is vitally important that (from the client's
perspective) the service is stateless. One object's use of a global
service must not impact any other object's use of the service.

For this reason I think it's important to conceptually separate
methods for using the service from methods for configuring the
service.

E.g., it's safe to use System.out wherever you want, but using
System.SetOut() is rather heinous if not carefully controlled.

> In any event, I wouldn't judge which is simpler by the reaction of a
> novice programmer. I've seen too many that think sprinkling magic
> numbers around the program is simpler.

A Java beginner isn't necessarily a novice programmer. Anytime a
programmer says in frustration, "Why won't it just let me X?!" or "I
can't believe I need to do X, Y, and Z just to accomplish Q!", there's
a big red flag about complexity. People experienced in a language are
used to its unnecessary complexities and tend to overlook them easily.

> So, among the options are:
> 1. using a static method, which implies a global, singleton
service,
> if not object.

I like this until something more is needed. As I mentioned, a global
service does not strike me as a bad thing when you're providing a
service that is global.

> 2. using a constructor (which perhaps just initializes a
Monostate),
> which implies client control over the creation of objects.

This seems like a clever trick to avoid having to change a lot of
client code during a refactoring when you actually do need different
instances all over the place. IMHO, YAGNI.

> 3. using a factory method, which implies to me that the client has
> no knowledge over whether a new object is being created or one is
> being pulled out of a pool (that may only have one element). To
others,
> such as yourself, this seems to imply a singleton.

As I mentioned, kind of a brain fart. Factory implies things are
being made. What factory really says to me is that I'm giving up
control of construction so that the factory can create a class I don't
know about (or shouldn't care about or don't know enough to choose) -
like a subclass of the class I asked for, or an implementer of the
interface I asked for. Factories have to do with abstraction, not
singleton-ness.

> Except for the amount of typing, I currently think that #3 is just
as
> simple and is more general than #1 or #2. I don't use #3
exclusively,
> however, and I'm willing to consider arguments for the alternatives.

I prefer #1 for global services, and #3 for hiding a variety of
implementations/subclasse so that client code doesn't need to know
when new implementations/subclasses are added. These are very
different uses. I would only ever use #2 if the client code
conceptually wanted control over object creation and instances. I
can't really think of a case where the client wants to believe it has
its own instance but there's no actual need for different instances,
except maybe as a step during a refactoring between a singleton and
multipletons (in either direction).

Best,
Matthew
azami@...
Your message has been successfully submitted and would be delivered to recipients shortly.