Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2006

Tip: Looking for answers? Try searching our database.

Singleton Pattern

Thread view: 
Adi - 25 Nov 2006 05:23 GMT
Dear all,

I have a question about singleton pattern. In my java user group,
someone said that this pattern should be avoided, but he didn't explain
the reason.

So I am curious here, is this statement true ?

Someone else replied that this pattern is hard to test and make other
classes tightly coupled with this Singleton class. Somehow I doubt it
but I also can find any argument for that. What I know is just because
this pattern is hard to test doesn't mean that this pattern should be
avoided right ? I use this pattern a lot of times and found it useful.

Do you have any comments ?

Thanks,
saotome - 25 Nov 2006 05:44 GMT
I personally use it plenty of times. I don't share your college's
opinion. I don't understand why it would create tight coupling vs. a
regular instantiation of an object.

> Dear all,
>
[quoted text clipped - 13 lines]
>
> Thanks,
rxreyn3@gmail.com - 25 Nov 2006 06:28 GMT
It's a matter of personal preference usually.  The decision I make is
on whether or not I can make static methods calls first.  If I can't
make static method to accompilsh what  a class needs to do, yet I need
to maintain a unique set of information, i'll create a singleton class.

Ryan

> Dear all,
>
[quoted text clipped - 13 lines]
>
> Thanks,
Karl Uppiano - 25 Nov 2006 08:38 GMT
> Dear all,
>
[quoted text clipped - 3 lines]
>
> So I am curious here, is this statement true ?

Sometimes, I suppose.

> Someone else replied that this pattern is hard to test and make other
> classes tightly coupled with this Singleton class. Somehow I doubt it
[quoted text clipped - 3 lines]
>
> Do you have any comments ?

If your design needs a singleton, then you should use a singleton. Perhaps
your colleague was referring to some of the potential pitfalls (everything
has pitfalls) described here:
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html
Mark Jeffcoat - 25 Nov 2006 10:08 GMT
> Dear all,
>
> I have a question about singleton pattern. In my java user group,
> someone said that this pattern should be avoided, but he didn't explain
> the reason.

There are a couple of really good reasons to avoid singletons:

First, because Singletons are Global Variables, returned from
the grave where we tried to bury them so many years ago. They're
very often used to pull in bits of extra state deep inside a
program, jumping out without warning or any sort of control.

(Most common form: If your singleton has a name like "Configuration",
you've got a cluster of global variables in a pretty wrapper.)

Second, because singletons are hard to test. To write useful
unit tests, you have to know that the behavior of the code
under test is the same as the behavior of the code in its
final environment. Singletons allow you to not only make
arbitrary changes in the environment, but they also introduce
an order dependence into your tests. Every test that runs
can change the state of your singleton, and that new state
is carried over to the next test. Since this order probably
is completely unrelated to the order in which the bits you're
testing would be used in production, your tests are going to be
much less likely to catch real problems--really, it's nearly
impossible to guarantee that the behavior of code under test
is not arbitrarily different than the same code in the
production environment.

Third, using a singleton denies the possibility of certain
extensions to your software. Someday, you're going to want
two instances of whatever you were doing originally, and then
many, and it's going to be annoying to have to run each
instance in a separate JVM. This has actually happened to me,
and I was, in fact, annoyed.

Reason 1 is enough: Globals are bad, because they will make
your software hard to understand, and harder to maintain.

Signature

Mark Jeffcoat
Austin, TX

Chris Uppal - 25 Nov 2006 11:56 GMT
> First, because Singletons are Global Variables, returned from
> the grave where we tried to bury them so many years ago.

I often read this, but I don't think there's an ounce of truth in it.

More accurately, I think:

There is a need (a perfectly genuine need) to be able to put data in some
"well-known" place where things can get at it.  And without the data (or its
location) needing to know about the users in advance (so the data is decoupled
from its users, even though the users are coupled to the data -- but that's
inevitable, it's part of the underlying logic, not an accident of poor design).

Global variables are one way of providing that.  And when used for that purpose
they work well.  Of course, they can be misused to create "spaggetti data".
But that doesn't mean that they are bad when used correctly.

One practical problem with global variables (considered as a technology
intended to meet the requirement described above), is the name-clash thing.
One solution to that is to use something like the Singleton pattern (or even
just a public static field) in Java.  That addresses exactly the same
underlying need, but vastly reduces (not eliminates) the problem with unwanted
name clashes.  As you say, Singletons are essentially the same as global
variable -- which is what you'd expect, they have been invented to address
exactly the same need.

After all, what is a DBMS if it is not a chunk of (mutable) data available to
all users at a well-known location ?  Indeed it is available enterprise-wide,
which puts poxy little Singleton classes in the shade ;-)   Are DBMS's without
problems ?   Of course not, and some of those problems are exactly the same as
the ones exhibited by other global varaiables (or Singletons) -- concurrent
access, over-tight coupling, brittleness -- but I don't think many pundits
would advocate scrapping the DBMS for those reasons.

There's nothing wrong with global data...

   -- chris
Mark Jeffcoat - 28 Nov 2006 01:08 GMT
>> First, because Singletons are Global Variables, returned from
>> the grave where we tried to bury them so many years ago.
>
> I often read this, but I don't think there's an ounce of truth in it.

I confess, I'm a little surprised. I thought I was making
a claim on a similar level to "breathing is useful".

> More accurately, I think:
>
> There is a need (a perfectly genuine need) to be able to put data in some
> "well-known" place where things can get at it.  And without the data (or its
> location) needing to know about the users in advance (so the data is decoupled
> from its users, even though the users are coupled to the data -- but that's

> Global variables are one way of providing that.  And when used for that purpose
> they work well.  Of course, they can be misused to create "spaggetti data".
> But that doesn't mean that they are bad when used correctly.

Okay. I certainly can't argue that it's possible to build
a correct and clear program that used globals to store that
data.

I see two potential problems:

First, it's not clear to me how I'm supposed to tell the
difference between globals done right, and "spaghetti data".
"Apply the intuition of an experienced programmer" probably
works quite well for you, but it doesn't seem particularly
helpful as advice to a novice. Would you care to take a stab
at offering a few guidelines on how to recognize and avoid
spaghetti data?

Second, I hate to lose the ability to analyze a method
entirely in terms of its parameters and the its object's
data (and thus have it easily testable). The way I solve
the problem you lay out above while keeping that ability
almost everywhere is to make sure that the classes that
implement the business logic of the program only use that
data in constructors and method calls; a method body never
has access to the global data store (which might be, as
you say, a DBMS).

Signature

Mark Jeffcoat
Austin, TX

Karl Uppiano - 28 Nov 2006 01:32 GMT
>>> First, because Singletons are Global Variables, returned from
>>> the grave where we tried to bury them so many years ago.
[quoted text clipped - 3 lines]
> I confess, I'm a little surprised. I thought I was making
> a claim on a similar level to "breathing is useful".

I think globals exist because there is a legitimate use for them.
Unfortunately, lazy programmers began to misuse them, and pretty soon
everyone was saying "globals are bad, m'kay?". Now it's just politically
incorrect to include them anywhere.

Any bad programming you can do with globals, you can do just as handily with
instance member variables.
Chris Uppal - 28 Nov 2006 15:44 GMT
> > > First, because Singletons are Global Variables, returned from
> > > the grave where we tried to bury them so many years ago.
[quoted text clipped - 3 lines]
> I confess, I'm a little surprised. I thought I was making
> a claim on a similar level to "breathing is useful".

Yes, I understood that.  Which is why I phrased my introductory remark rather
more strongly than was actually justified ;-)

> First, it's not clear to me how I'm supposed to tell the
> difference between globals done right, and "spaghetti data".
[quoted text clipped - 3 lines]
> at offering a few guidelines on how to recognize and avoid
> spaghetti data?

Can you give a reasonable summary of "functions done right" as opposed to
"spaghetti code" ?  I can't.  The best I can do is offer some rules of thumb,
and/or heuristics.  Some, rather off the top of my head, and probably mutually
contradictory (as is to be expected of heuristics).

Bad, or at least suspicious:
Lots of globals (say, more than the number of major modules).
A global which is used in only a few closely related places.
A global with no obviously sensible (non-arbitrary) name.
A global which changes its value even when the overall behaviour of the program
doesn't change.
A global used in modules which don't obviously need to know about it.

Good, or at least promising:
A global corresponding to something in the underlying logical design, rather
than a mere implementation artefact (e.g. something you could easily explain to
a user).
A global corresponding to something in the "ambient" (i.e. the execution
environment of the whole program -- things like the OS, utility modules like
Collections, and other stuff that a program can just assume).
A global which removes the need for lots of duplicated code.
A global which removes the need for pass-though parameterisation (Supplied by A
to B, but not used by B except to pass it on to C).

Perhaps a more indirect guideline:  Imagine that an experienced
programmer/designer is looking at the application/library.  S/he is familiar
with the application domain, and with the functional requirements of the
program, but has never seen any of the code.  Now you tell them briefly about
your global.  Would they be able to guess with nearly perfect accuracy which
parts of your code used it ?  If so then you are probably on the right track.

"Global", of course, in the above is to be understood as anything which
implements a global-like semantics, such as an application-wide registry, or
use of the Singleton pattern, as well as actual global variables.  Note that
mutable static fields often count as global-like even if they are not used to
implement a classical Singleton pattern.

> Second, I hate to lose the ability to analyze a method
> entirely in terms of its parameters and the its object's
[quoted text clipped - 5 lines]
> has access to the global data store (which might be, as
> you say, a DBMS).

I think that's a good statement of where we disagree ;-)   For me there's a
design decision to be made: on one hand you can parameterise a module on
<something> explicitly, on the other hand you can remove (or re-express) that
parameterisation by representing the <something> as part of the ambient.  In
one case you end up passing the <something> around in parameters or as instance
state; in the other case you use a global.  There are advantages and
disadvantages, both theoretical and practical, to both approaches.  I admit
that the former comes out on top much more often than the latter.

As an aside: I don't really buy the testing argument -- it seems to me that if
the design of the application and/or the nature of the testing environment is
such that global-like data makes unit testing difficult, then either the app or
the testing environment is pretty deeply flawed.  Fix whichever is broken, even
if you /don't/ use globals.

   -- chris
Mark Jeffcoat - 29 Nov 2006 21:52 GMT
>> First, it's not clear to me how I'm supposed to tell the
>> difference between globals done right, and "spaghetti data".
[quoted text clipped - 8 lines]
> and/or heuristics.  Some, rather off the top of my head, and probably mutually
> contradictory (as is to be expected of heuristics).

Yeah. I was aware that I was asking a rather broad question;
thanks for the effort you put into your answer.

> Bad, or at least suspicious:
> Lots of globals (say, more than the number of major modules).
[quoted text clipped - 3 lines]
> doesn't change.
> A global used in modules which don't obviously need to know about it.

Unsurprisingly, I agree with everything on this list.

> Good, or at least promising:
> A global corresponding to something in the underlying logical design, rather
[quoted text clipped - 6 lines]
> A global which removes the need for pass-though parameterisation (Supplied by A
> to B, but not used by B except to pass it on to C).

But some of these make me nervous. I'm kind of like
pass-trhough parameterization; no surprises, and I know
at a glance what objects are involved in the method. I
do with Java had better (well, any) meta-syntax facilities,
so you could replace a verbose and un-informative method
delegation with a simple pointer to the class you're delegating
too.

I've already proposed a different solution to the
ambient environment that's conceptually quite similar;
the biggest difference that I can see is that I'm proposing
to explicitly pass the enviroment object around to anything
that needs it.

A matter of taste, of course.

> "Global", of course, in the above is to be understood as anything which
> implements a global-like semantics, such as an application-wide registry, or
> use of the Singleton pattern, as well as actual global variables.  Note that
> mutable static fields often count as global-like even if they are not used to
> implement a classical Singleton pattern.

I'm actually largely okay with immutable static fields ...
really, immutable anything that can be assigned a final
value at compile time. Relaxing that restriction to
assign-only-once fields at least is enough to completely
avoid the spooky action at a distance problem, where the
behavior of one part of the program changes when a not-
obviously-related part makes a change to a shared value.

> As an aside: I don't really buy the testing argument -- it seems to me that if
> the design of the application and/or the nature of the testing environment is
> such that global-like data makes unit testing difficult, then either the app or
> the testing environment is pretty deeply flawed.  Fix whichever is broken, even
> if you /don't/ use globals.

In this context, when I say "testing", I'm talking about constructing
unit tests, not discovering and fixing problems. I apologize for being
unclear.

Signature

Mark Jeffcoat
Austin, TX

Chris Uppal - 30 Nov 2006 13:15 GMT
> I
> do with Java had better (well, any) meta-syntax facilities,
> so you could replace a verbose and un-informative method
> delegation with a simple pointer to the class you're delegating
> too.

I don't suppose it would be particularly difficult to add-on something like
that using the same kind(s) of bytecode manipulation technologies as the AOP
folks.  Scan for fields with an @Delegates annotation, decide (perhaps from
further annotations) what "interfaces" to delegate to each, and inject some
simple method definitions into the classfile -- nothing to it really ;-)

> I've already proposed a different solution to the
> ambient environment that's conceptually quite similar;
> the biggest difference that I can see is that I'm proposing
> to explicitly pass the enviroment object around to anything
> that needs it.

I missed that somehow, and can't find it now.  Can you post a link ?

Anyway, guessing what you mean from "I'm proposing to explicitly pass the
environment object around to anything that needs it"; I think there's a fairly
major problem with that.  If you only pass the environment to
objects/operations where it is actually needed, then you have an over-strong
coupling (IMO) between the invoking code and the implementation code.  You can
easily remove that coupling by passing the environment object around
unconditionally (and I've done that sort of thing before too); but then you
have just reintroduced your globals, but in a different dress.

> > As an aside: I don't really buy the testing argument -- it seems to me
> > that if the design of the application and/or the nature of the testing
[quoted text clipped - 5 lines]
> unit tests, not discovering and fixing problems. I apologize for being
> unclear.

I'm not sure whether you have misunderstood me -- it sounds as if you /might/
have -- but I also was talking about difficulty (or lack of it) in constructing
unit tests (and other fine-granularity tests).

   -- chris
RedGrittyBrick - 02 Dec 2006 12:08 GMT
>>>> First, because Singletons are Global Variables, returned from
>>>> the grave where we tried to bury them so many years ago.
[quoted text clipped - 8 lines]
>> First, it's not clear to me how I'm supposed to tell the
>> difference between globals done right, and "spaghetti data".
... <snippage> ...
>> Would you care to take a stab
>> at offering a few guidelines on how to recognize and avoid
>> spaghetti data?

<snip handy rules of thumb>

As someone relatively new to Java I can see the sense in what you are
saying but I can't see how else to implement certain things.

I think I have three or more areas where I'm either using singletons,
where singletons would be useful, or where I am doing something that I
think is related (but I may be misunderstanding) Maybe someone could
suggest best practice for some or all of these? ...

1) Constants that are used in several classes. In one case these are key
values for user preferences that I am storing in a properties file. For
example 'static String WINDOW_SIZE = "window_size";'. By using the
constant, the compiler will pick up any typing errors, If I type
'prop.get("window-size");' I'll not get a compiler error, may not get a
run-time error but will get unexpected behaviour. So in my class that
contains my main() I define these as static constants. Elsewhere I use
these constants as prop.get(MainClass.WINDOW_SIZE) etc. These are
clearly global, I don't see a cleaner alternative.

2) Shared single resources. My example is a database connection. My app
opens one connection, various classes use this to perform SQL
transactions on unrelated tables etc. I could add a `connection`
variable to every method call, but this makes for long strings of
arguments to method calls, in some cases just so the variable can be
passed on to other method calls (covered in Chris's rules of thumb).
So I have a singleton to create the connection and it provides a public
DBClass.getConnection() to return the connection. Obviously I have to be
careful to avoid concurrent use of the connection. I don't know of a
better way to share a single resource of this sort - is there one?

3) An "owner" for JDialogs. My App has a single frame. Many classes need
to popup modal Dialogs or JOptionPanes, these need an owner to be
specified. Currently I'm passing it as a parameter to the constructor of
any class that needs it. I'm not entirely happy with this approach. The
alternative seems to have a static variable MainClass.frame. Is there a
better approach?

4) As an aside to the above, I sometimes need various classes to be able
to things done by the main class, for example, update a status message
at the bottom of the main window. To achieve this I pass a reference to
the main JFrame in the constructor of classes created. So sometimes I
have ...

class Mainform extends JFrame {
    Mainform() {
        ...
        FooClass f = new FooClass(this);
        BarClass b = new BarClass(this);
        ...
    }
    public void setStatus(String text) { ... }
}
class FooClass {
    JFrame parent;                     // *** Note "JFrame" ***
    FooClass(JFrame parent) {
        this.parent = parent;
    }
    xyzzy() {
        ...
        JOptionPane.showMessageDialog(parent, "Error" ...);
        ...
    }
}
class BarClass {
    Mainform parent;                     // *** Note "Mainform" ***
    BarClass() {
        this.parent = parent;
    }
    plugh() {
        ...
        parent.setStatus("Important thing accomplished");
        ...
        JOptionPane.showMessageDialog(parent, ...);
        ...
    }
}
Having a Mainform variable in the constructor of BarClass means I can't
re-use the BarClass in another application. I also have this
JFrame/Mainform choice for parameter type that I find hard to resolve.
Any suggestions?

Sorry for droning on, I hadn't intended to be this wordy :-) Feedback
appreciated though.
andrewmcdonagh - 02 Dec 2006 18:30 GMT
On Dec 2, 12:08 pm, RedGrittyBrick <RedGrittyBr...@SpamWeary.foo>
wrote:

snipped...

> 2) Shared single resources. My example is a database connection. My app
> opens one connection, various classes use this to perform SQL
[quoted text clipped - 6 lines]
> careful to avoid concurrent use of the connection. I don't know of a
> better way to share a single resource of this sort - is there one?

Noooo.......

Having a Singleton DB connection is the absolute worst use of the
pattern - you don't need to enforce that there is only one connection,
you simply need to store the (currently needed) single connection
somewhere.

Choosing that usage, will cause you major problems when you need a
second connection.

A better approach is for a singleton container which could return a
number of connections based upon some form of ID.

connectionOne = Connections.getConnectionFor(db1);
connectionTwo = Connections.getConnectionFor(db2);
RedGrittyBrick - 02 Dec 2006 19:02 GMT
> On Dec 2, 12:08 pm, RedGrittyBrick <RedGrittyBr...@SpamWeary.foo>
> wrote:
[quoted text clipped - 27 lines]
> connectionOne = Connections.getConnectionFor(db1);
> connectionTwo = Connections.getConnectionFor(db2);

Thanks Andrew, I'll ponder that.
Daniel Pitts - 03 Dec 2006 18:07 GMT
[Snip previous discussion]
> As someone relatively new to Java I can see the sense in what you are
> saying but I can't see how else to implement certain things.
[quoted text clipped - 13 lines]
> these constants as prop.get(MainClass.WINDOW_SIZE) etc. These are
> clearly global, I don't see a cleaner alternative.
Constants are not the same concept as singletons.  Also, Java 1.5
supports enums, which are a better approach to those situations.  I
would use this to help qualify one case where a singleton is bad:

A singleton is a bad choice when you may ever want to dynamically
change the behaviour of the object depending, such as by using
polymorphism.  Having a global String, or Integer object, does not fall
under this category.

> 2) Shared single resources. My example is a database connection. My app
> opens one connection, various classes use this to perform SQL
[quoted text clipped - 6 lines]
> careful to avoid concurrent use of the connection. I don't know of a
> better way to share a single resource of this sort - is there one?

Use the Dependency Injection pattern (a specific use of the Inversion
of Control pattern).  You're framework creates the single resource at
the begining of executions (such as the main method), and the framework
makes sure it gets where it needs to go (see springframework.org for a
good IoC platform)

> 3) An "owner" for JDialogs. My App has a single frame. Many classes need
> to popup modal Dialogs or JOptionPanes, these need an owner to be
> specified. Currently I'm passing it as a parameter to the constructor of
> any class that needs it. I'm not entirely happy with this approach. The
> alternative seems to have a static variable MainClass.frame. Is there a
> better approach?
Singleton in this approach almost garuanties that you will never be
able to extend your application to have more than a single frame.  The
best option here is to propagate the owner some how.  Not necessarily
in the constructor. If you have a reference to any component, you can
retrieve its owning window from that.

> 4) As an aside to the above, I sometimes need various classes to be able
> to things done by the main class, for example, update a status message
[quoted text clipped - 39 lines]
> JFrame/Mainform choice for parameter type that I find hard to resolve.
> Any suggestions?

Is it important to have parent be a "Mainform"? Could it just be a
"JFrame"

Instead of using "Mainform.setStatus", consider having Mainform
implement "StatusListener", and having any class that can change the
status, do so with an event.

> Sorry for droning on, I hadn't intended to be this wordy :-) Feedback
> appreciated though.

I hope this helps. Feel free to break any part of this message apart
and ask quesions on portions of it.

Good luck,
Daniel.
Chris Uppal - 04 Dec 2006 15:41 GMT
> 1) Constants that are used in several classes.

Most people wouldn't see the use of such constants as problematic.  The biggest
source of problems from globals, singletons, or whatever, is that their values
can change.  If the value is intended to be constant (and /is/ constant ;-)
then the problems are (at worst) much reduced.

> 2) Shared single resources. [...] I don't know of a
> better way to share a single resource of this sort - is there one?

In your particular example of database connections, you might want to consider
what would happen if you changed your design to use a small pool of connections
(e.g to make it easier to manage concurent use).  The questions to ask yourself
are: "am I likely to want to make that kind of change?", "does my current
design make it hard to change that way?", and "is what I gain from my current
design now enough to 'pay for' whatever pain we will incur /if/ we later want
to change?".  I.e. it's an engineering trade-off, and only you know what values
to plug into the decision.  FWIW, I think that most people, in most
circumstances, would choose not to use a Singleton for this.

> 3) An "owner" for JDialogs. My App has a single frame. Many classes need
> to popup modal Dialogs or JOptionPanes, these need an owner to be
> specified. Currently I'm passing it as a parameter to the constructor of
> any class that needs it. I'm not entirely happy with this approach. The
> alternative seems to have a static variable MainClass.frame. Is there a
> better approach?

No idea, I'm afraid.  (As an aside, I don't like GUIs which make use of popup
dialogs, except very short-lived ones like file-selection dialogs.)  At a
guess, I'd suggest that if your code doesn't naturally have access to a
suitable JFrame at the point where it discoveres that it needs to popup a
dialog, then that might indicate that you are mixing presentation and domain
logic too much.

> 4) As an aside to the above, I sometimes need various classes to be able
> to things done by the main class, for example, update a status message
> at the bottom of the main window. To achieve this I pass a reference to
> the main JFrame in the constructor of classes created.

Seems as if you are passing too much information to the other classes.  They
don't need to know about the whole JFrame/Mainform to display status text.  If
the "other classes" are GUI classes, then it seems that all they need is a
refernce to, say, a JLabel which they update.  If they are not GUI classes,
then perhaps they should be updating some sort of StatusModel, or maybe
triggering StatusChanged events which your GUI would observe.

The real problem here (as you understand, I think) is that the "other classes"
are too tightly coupled to the main class(es).  But using Singleton would not
materially affect the degree of coupling -- the code would /look/ less coupled,
but that would only be sweeping the problem under the mat.  The two designs
would still be connected together more than they should be, and when that
happens it doesn't matter how you write the code (passing paramenters, using
singletons, or whatever), the coupling is real, and won't go away.

   -- chris
andrewmcdonagh - 02 Dec 2006 17:50 GMT
On Nov 28, 3:44 pm, "Chris Uppal"
<chris.up...@metagnostic.REMOVE-THIS.org> wrote:
> > > > First, becaus

snipped...

> As an aside: I don't really buy the testing argument -- it seems to me that if
> the design of the application and/or the nature of the testing environment is
[quoted text clipped - 3 lines]
>
>     -- chris

Its not so much as they make it difficult, its that they make the tests
brittle at best, or enforce an execution order of them at worst.

The usual way around these issues is to add some form of 'reset'
mechanism to the Singleton, so that each unit test can 'reset' the
state of the singleton before starting.

However, the better approach is to have the code under test, not know
that the object is a Singleton, by passing it to the code, instead of
the code using the static 'getInstance()' method.

If we then start passing around the Singleton instance to use, instead
of using its static fetch method, then we should ask ourselves...
"Why don't I just create one instance, instead of forcing a Singleton?"

Singletons (IMO) are best used as a global Container for various other
objects. AKA a Toolbox.

In 10 years of development I've rarely found a real need for enforcing
the 'must only be one' concept, that the Singleton is designed for.  I
have seen countless usages of Singleton, as a way of accessing from
anywhere, a certain type of object, or values it holds.

Andrew
Chris Uppal - 04 Dec 2006 15:46 GMT
> In 10 years of development I've rarely found a real need for enforcing
> the 'must only be one' concept, that the Singleton is designed for.  I
> have seen countless usages of Singleton, as a way of accessing from
> anywhere, a certain type of object, or values it holds.

Which is almost exactly what I said myself (in the stuff that has been
snipped).  Singleton pattern is useful, when used judiciously, but whatever you
do, don't get fooled into thinking you should enforce singularity.

Personally, I think the pattern is ill-named.  "Distinguished Instance", or
"Well-known Value", would be better, but you can't change the names of Patterns
at will -- their names (however misleading) are the most valuable thing about
them.

   -- chris
Chris Thomasson - 25 Nov 2006 10:17 GMT
> Dear all,
>
[quoted text clipped - 11 lines]
>
> Do you have any comments ?

http://appcore.home.comcast.net/vzdoc/atomic/static-init/

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/c7d417
e0b8aa516d

Chris Uppal - 25 Nov 2006 12:09 GMT
> Someone else replied that [Singleton] is hard to test and make other
> classes tightly coupled with this Singleton class. Somehow I doubt it
> but I also can find any argument for that.

Singleton /can/ be a symptom of poor design.  The worst thing about it (IMO) is
that people tend to focus on the idea that you /must/ only have one instance.
There is nothing wrong with /actually/ having only one instance, plus a
well-known way to find it; but for some weird reason people often go beyond
that and make it impossible to create other instances.  That is restrictive,
unnecessary, and brittle.

Give you an example.  Say we have some printer settings, and we'd like them to
be globally available.  That's all fine so far -- a perfectly reasonable thing
to want to do.  So we set up a class, PrinterSettings, and arrange that there
shall be a well-known instance (probably populated from the user's personal
preferences).  We'll make that Singleton instance available from a static
method, PrinterSettings.getDefault().  That's still fine and dandy, and is
exactly the kind of thing that Singleton pattern is good for.  But now, some
idiot decides to make it impossible to create /other/ instances of our
Singleton's class, that has all sorts of bad effects:

  1)  We probably can't risk modifying the Singleton instance, because it
might be in use by more than one thread.  That was a problem with our original
design too, of course, and so we may (depending on the application) need a way
to avoid that problem.  In our original design, the solution was simple -- just
make a copy of the PrinterSettings.getDefault() whenever we need a stable set
of settings.  But with this new restriction we can't do that, so we have to
design some sort of complicated (and probably brittle) locking protocol to
allow us to "freeze" the settings while we are actually using them.

   2) Nothing, /nothing/, has actually been gained by the restriction.  The
software is not more flexible, more reliable, nor easier to understand.  Its
just a bit of programmer fascism -- "Anything not mandatory is forbidden!".
Probably driven by insecurity.

   3) Since we now have this single Singleton, programmers will be tempted to
write the code on the assumption that /everything/ will use that instance --
why pass it in a parameter when the called code can find the PrinterSettings
object directly by itself ?  That leads to brittleness.  If (or more likely,
when) the requirements change, e.g. to have two printers in the system, you
have to track down and eliminate all the code which /should/ have been
parameterised on the PrinterSettings to use, but which have hard-wired the
one-and-only-one Singleton assumption instead.

There may be situations where a one-and-only-one rule /is/ necessary -- but
they are very rare[*], and crop up far less often than legitimate needs for a
properly-written Singleton.

As to the "increased coupling" assertion.  That's not really a problem of
Singleton as such, but of its typical expression using static methods -- all
static methods (and fields) lead to increased coupling (and so does direct us
of constructors, but that's another story...)

   -- chris

[*] I can't think of any off the top of my head.
Lionel - 28 Nov 2006 01:26 GMT
[snip]
> Give you an example.  Say we have some printer settings, and we'd like them to
> be globally available.  That's all fine so far -- a perfectly reasonable thing
[quoted text clipped - 5 lines]
> idiot decides to make it impossible to create /other/ instances of our
> Singleton's class, that has all sorts of bad effects:

An interesting point you have made there. I had not considered this before.

I use Singleton in one of my programs. It acts as an interface to a
database - no problems there. Originally it was a normal implementation
of the Singleton pattern but I found that every time I wanted to use it
I had to do the following:

SingletonClass singletonInstance = SingletonClass.getInstance();
singletonInstance.saveObject(objectInstance);

So I got sick of this and changed the methods to static methods to
produce equivalent code:

SingletonClass.saveObject(objectInstance);

I can't possibly imagine where in my program it would ever be necessary
to have an instance of this class, but I'm sure someone could think up
something valid. So does that mean I should go back to the original
design and add the additional annoying code everywhere?

Lionel.
Andreas Leitgeb - 28 Nov 2006 10:12 GMT
> SingletonClass singletonInstance = SingletonClass.getInstance();
> singletonInstance.saveObject(objectInstance);

ok, so just imagine that some day you want to extend SingletonClass
to ExtSingletonClass, which overrides  saveObject.

Doing it the "right" longish way, just means that you statically
store an instance of the ExtSingletonClass and getInstance will
return the derived object, and saveObject will be called from
the derived object.

If instead you made saveObject a static method of SingletonClass,
you'd have to modify all places where it's used.

Now, there is the obvious point of criticism:
 Why should one create an ExtSingletonClass, rather than just
    modifying the original SingletonClass?
 I can't give any real answer, except a dogmatic one: sometimes
    you just have to ...   Sometimes, especially in the vicinity
    of Corba, the actual class implementing "SingletonClass" isn't
    even known at compile time, but specified per name at runtime.

So for your progs, you just ask yourself:
 Will this SingletonClass object ever need to be replaced with
 an object of a derived Class?
If you can sufficiently safely answer "no" to that question,
  then go ahead and use static methods. The lesser typing might
  be worth the small risk of having made a wrong decision :-)
Otherwise stick to getInstance() and non-static members.
Chris Uppal - 28 Nov 2006 15:04 GMT
> SingletonClass singletonInstance = SingletonClass.getInstance();
> singletonInstance.saveObject(objectInstance);
[quoted text clipped - 3 lines]
>
> SingletonClass.saveObject(objectInstance);

I don't see anything much wrong with that.  Or at least not inherently.  I
would hope that you've kept the old interface available for code which doesn't
use the Single instance.  So that the second form is just a short-cut for the
former, rather than a redesign of the application to hard-wire the knowledge
that there /cannot/ be another instance (the first form only hard-wires the
knowledge that there is /a/ special instance, but not that there is only one).

   -- chris
Lionel - 29 Nov 2006 03:10 GMT
>> SingletonClass singletonInstance = SingletonClass.getInstance();
>> singletonInstance.saveObject(objectInstance);
[quoted text clipped - 10 lines]
> that there /cannot/ be another instance (the first form only hard-wires the
> knowledge that there is /a/ special instance, but not that there is only one).

Just a reply to acknowledge that I've read the two responses to my
previous post and to say thanks :).

Lionel.
Arne Vajhøj - 25 Nov 2006 13:55 GMT
> I have a question about singleton pattern. In my java user group,
> someone said that this pattern should be avoided, but he didn't explain
[quoted text clipped - 9 lines]
>
> Do you have any comments ?

Singleton is a valid pattern.

Most of the criticism found on the net is ridiculous ("if you implement
it wrong then it will not work" type).

The only real problem I can think of is a modifiable singleton in a
clustered environment (or other multi JVM environment).

Arne
rxreyn3@gmail.com - 25 Nov 2006 18:33 GMT
I'll be the first to admit that I have learned alot in this short
discussion.  Even if I don't agree.

Ryan

Arne Vajh?j wrote:
> > I have a question about singleton pattern. In my java user group,
> > someone said that this pattern should be avoided, but he didn't explain
[quoted text clipped - 19 lines]
>
> Arne
andrewmcdonagh - 25 Nov 2006 20:20 GMT
> > I have a question about singleton pattern. In my java user group,
> > someone said that this pattern should be avoided, but he didn't explain
[quoted text clipped - 17 lines]
>
> Arne

The Singleton is a valid pattern.

The Singleton is the most used pattern.

The Singleton is the most abused pattern (e.g. used mainly for finding
something at a well know location, rather than to enforce 'just one
instance')

See:
http://groups-beta.google.com/group/comp.object/browse_thread/thread/54abf37ca7b
7abda/0539f2454634cfca?lnk=st&q=Singleton+Pattern&rnum=5#0539f2454634cfca


The majority of times, having a global access to something is  the
usual reason for creating a Singleton.  In these cases, its not a
singleton that was required, but a singleton containing mutliple items
- in other works a 'Container' or 'Toolbox'
Arne Vajhøj - 25 Nov 2006 21:45 GMT
>>> I have a question about singleton pattern. In my java user group,
>>> someone said that this pattern should be avoided, but he didn't explain
[quoted text clipped - 11 lines]
>> The only real problem I can think of is a modifiable singleton in a
>> clustered environment (or other multi JVM environment).

> The Singleton is a valid pattern.
>
[quoted text clipped - 11 lines]
> singleton that was required, but a singleton containing mutliple items
> - in other works a 'Container' or 'Toolbox'

As with most patterns there are a cases where it can be debated whether
a specific pattern is the best solution or not.

Singleton is probably the most widely abused. But no surprise if it
is the most widely used.

But from a practical point of view, then I would say that even
in the cases where singleton is not the best solution, then it
is usually not a bad solution either.

There are many much worse diseases than being over enthusiastic
about singletons.

Arne
Karl Uppiano - 25 Nov 2006 22:58 GMT
> As with most patterns there are a cases where it can be debated whether
> a specific pattern is the best solution or not.
[quoted text clipped - 8 lines]
> There are many much worse diseases than being over enthusiastic
> about singletons.

I tend to agree. The question should not be "is the design pattern good or
bad?" but rather, "does the solution require this design pattern?". A good
design should attempt to choose a "good one" from the entire catalog of
design patterns. All engineering is a trade-off, so there probably isn't a
"best one", only one that doesn't suck too badly in any likely use-case.
Chris Uppal - 26 Nov 2006 15:27 GMT
> I tend to agree. The question should not be "is the design pattern good or
> bad?" but rather, "does the solution require this design pattern?". A good
> design should attempt to choose a "good one" from the entire catalog of
> design patterns.

You may not have meant that exactly how it sounded, but if you do then I
disagree profoundly.  A good design is created on its own merits, /not/ by
scanning some menu of available patterns.

   -- chris
Arne Vajhøj - 26 Nov 2006 16:20 GMT
>> I tend to agree. The question should not be "is the design pattern good or
>> bad?" but rather, "does the solution require this design pattern?". A good
[quoted text clipped - 4 lines]
> disagree profoundly.  A good design is created on its own merits, /not/ by
> scanning some menu of available patterns.

The difference between:

A) Create a good design based on your experience and knowledge including
   knowledge about established patterns.

B) At some point in the design process make a quick check on whether
   the problem matches an established pattern for design.

is not that big.

It is rather common to assume that if two solutions are technical
equally good, then it is best to choose the most well known
solution, because that makes the code more readable/maintainable.

Arne
Chris Uppal - 28 Nov 2006 15:16 GMT
> A) Create a good design based on your experience and knowledge including
>     knowledge about established patterns.
[quoted text clipped - 3 lines]
>
> is not that big.

True.  My objection is to the use of Patterns as if they were a menu of
available design options.  I would /hate/ to see a (would-be) designer saying
(or thinking) something like "Blast!  None of the Patterns fit this case -- I
shall have to invent something".  That is, to my mind, /exactly/ the wrong way
around.

Of course, knowledge of existing working designs is vital imput to the design
process -- but it's entirely irrelevant whether the community has developed an
accepted Pattern Name for <some design that you've seen before>.  (Which means
I disagree with your last paragraph (not quoted)).

Put it this way: the idea I'm objecting to of what Patterns are for, and of how
they are to be used,  doesn't correspond to either (A) or (B).

   -- chris
Arne Vajhøj - 07 Dec 2006 03:52 GMT
>> A) Create a good design based on your experience and knowledge including
>>     knowledge about established patterns.
[quoted text clipped - 9 lines]
> shall have to invent something".  That is, to my mind, /exactly/ the wrong way
> around.

I agree on that.

> Of course, knowledge of existing working designs is vital imput to the design
> process -- but it's entirely irrelevant whether the community has developed an
> accepted Pattern Name for <some design that you've seen before>.  (Which means
> I disagree with your last paragraph (not quoted)).

Here it is:
#It is rather common to assume that if two solutions are technical
#equally good, then it is best to choose the most well known
#solution, because that makes the code more readable/maintainable.

It does matter if it is a well known technique.

It simply makes maintenance easier if the programmer working
on it recognize it.

It does not matter for the code whether it has a name or not,
but it can make communication easier if it has a globally
accepted name.

Arne
Chris Uppal - 08 Dec 2006 15:45 GMT
[me:]
> > Of course, knowledge of existing working designs is vital imput to the
> > design process -- but it's entirely irrelevant whether the community
[quoted text clipped - 15 lines]
> but it can make communication easier if it has a globally
> accepted name.

I'd put it that it is important for maintenance that the person working on the
code understands[*] how it is structured (including any conventions which
should be followed but are not actively enforced) and why it is structured that
way.  The way(s) to achieve that are well understood -- clear code, good
comments (and any other documentation).

What established patterns give you is a short-cut towards good documentation --
a few words can establish an understanding of what the designer had in mind
(including pointing out parallels with other system); leaving only the details
to be filled in.  So, patterns definitely help.

But I wouldn't choose a design just on the basis that it was less effort to
document.  Less effort for this reason, anyway.  Designs which require less
explanation are certainly much to be preferred over ones which require more --
but patterns don't (IMO) reduce the amount of explanation needed, they just
streamline its expression.

   -- chris

[*] Although one of the skills that a good maintenance programmer /may/ have is
to work effectively without full understanding.  I can't do it myself, but I
have worked with people who can.  I think they work by some sort of
pattern-matching (not Pattern-matching ;-)
Karl Uppiano - 26 Nov 2006 19:41 GMT
>> I tend to agree. The question should not be "is the design pattern good
>> or
[quoted text clipped - 6 lines]
> disagree profoundly.  A good design is created on its own merits, /not/ by
> scanning some menu of available patterns.

A good design is created on its own merits, but IME, a large application is
usually built up from a judicious selection of standard components and
design patterns: For loops, while loops, try/catch blocks, if/else blocks,
switch statements, goto's, functional decomposition, object orientation,
threads, critical sections, mutexes, semaphores, stacks, queues, arrays,
lists, vectors, hash maps, singletons, resource adapters, enterprise service
busses, and so on, every one a design pattern of some sort.

The actual design is application-specific of course, and its quality depends
on the knowledge, ingenuity and creativity of the designer. However, in a
modular, object-oriented world, re-use is encouraged. Therefore, I usually
*do* scan some menu, in my mind, of available modules and design patterns,
not always consciously of course -- starting with the JDK API or C++ object
libraries, Google, -- looking for parts, to see if someone already invented
what I need. That's the "research" part of R&D. In many cases, I will extend
or modify what's available. If nothing is available, then I will create my
own module from scratch as a last resort. Of course, the
application-specific "glue" logic is usually not available off-the-shelf.

My particular coding style comes from the electronics industry, where I
started my career. In electronics, everything is modular: Resistors,
capacitors, inductors, transistors, integrated circuits... Sure, you could
make your own components from scratch, but unless you're in that line of
work, it is extremely time-consuming and fraught with difficulty. So,
vendors build solutions from a menu of available parts and design patterns -
e.g., most transistor audio amplifiers are based on the same tried and true
design pattern, modified to meet specific requirements. But from these
standard components and design patterns, I can build a cell phone, a
wireless router, a television, microwave oven...
andrewmcdonagh - 25 Nov 2006 20:16 GMT
> Dear all,
>
[quoted text clipped - 13 lines]
>
> Thanks,

This has been discussed to death during the last 10 years......

Take a look at
http://groups-beta.google.com/group/comp.object/browse_thread/thread/54abf37ca7b
7abda/0539f2454634cfca?lnk=st&q=Singleton+Pattern&rnum=5#0539f2454634cfca


for such a discussion.

Andrew
Adi - 25 Nov 2006 21:08 GMT
> This has been discussed to death during the last 10 years......
> Take a look at
http://groups-beta.google.com/group/comp.object/browse_thread/thread/54abf37ca7b
7abda/0539f2454634cfca?lnk=st&q=Singleton+Pattern&rnum=5#0539f2454634cfca

> for such a discussion.
> Andrew

Nice thread, thanks :)

Like ryan, I've learned a lot from here.
Daniel Pitts - 25 Nov 2006 21:13 GMT
> Dear all,
>
[quoted text clipped - 13 lines]
>
> Thanks,

The main reason is that it hinders Unit testing, but there are many
other good arguments against singletons as well.

The alternative is often the use of Dependency Injection.  This allows
you to decouple the process of obtaining an object from the class
altogether.  A class which uses a Singleton will have to know exactly
where to get it, and therefor coupling it to the Singleton.  A class
which utilizes Dependency Injection will know that it wants the
"Singleton" object, but instead of asking for it directly, it will be
given it by some outside source.

Lets give an analogy in psuedo-Java:

class Plant {
   double lightObsorbed = 0;
   void obsorbLight() {
        listObsorbed +=
LightSourceSingletonFactory.getLightSource().getLightInWatts();
   }
}

the Plant class is now coupled to LightSourceSingletonFactory and the
LightSource interface.  While it is not coupled to the implementation
of LightSource.

class Plant {
   LightSource lightSource;
   void obsorbLight() {
        listObsorbed += lightSource.getLightInWatts();
   }

  void setLightSource(LightSource lightSource) {
      this.lightSource = lightSource;
  }
}

Now, plant is no longer coupled to a singleton factory at all, and only
the interface of LightSource.  This would be useful of some day, your
business logic needed to have both indoor plants (class LightBulb
implements LightSource), and outdoor plants (class Sun implements
LightSource).

It also allows you to have a unit test with a "mock" LightSource
object.

Dependency Injection is a subcategory of Inversion of Control.  The
basis of the spring framework.

While the Singleton pattern DOES have uses, there are often other ways
to achieve the same goal which lend themselves to a more flexible
architecture.  If you only need to ensure that there is only one
instance of a particular class (eg. for a resource heavy object), you
can still use DI and IoC, especially since the classes themselves don't
do any form of object instansiation or retrieval.

It removes the burdon of object instantiation or retrieval from the
business domain, and puts it into the framework.

Hope this helps,
Daniel.
Nirav - 26 Nov 2006 08:46 GMT
> Dear all,
>
[quoted text clipped - 13 lines]
>
> Thanks,

I've few views of mine apart from the useful discussion here.
Personally, I find singletons handy in most programming environments.
My take on singleton is: never use them unless its inevitable (e.g.
config registries and stateless utilities). Singleton implementations
can easily become difficult to unit test, mock; which results in severe
problems in large applications (and i hate spending time on instance
recreation hacks, yuk). Most of the time I endup implementing minor
testable variant of it, called monostate.

- Nirav  Thaker
Ed - 28 Nov 2006 08:02 GMT
Adi skrev:

> Dear all,
>
> I have a question about singleton pattern.
>
> Thanks,

I won't add to the excellent debate on whether you should or should not
use singletons, but it should be pointed out that there's a theorem
called (oh, let's say) The Rationalisation Theorem which claims that
any number of singletons within a given program can be reduced to one
singleton without loss of ... well ... singletonness. (Interesting to
note that this theorem wouldn't hold if the singleton didn't relate to
both single instances and public access - a point for which it's often
(and often correctly) maligned.)

Say you have two singletons:
com.adi.model.ConcreteModelSingleton and
com.adi.view.ConcreteViewSingleton

It's possible to tear an interface - ModelSingleton and ViewSingleton -
from both and have them register their instances in a new singleton:
com.adi.common.SystemSingleton

And then either remove the single-instance-guaranteeing machinery from
the first two singletons themselves and put this in the
SystemSingleton, or remove the public access modifier from the first
two singletons (though this means having to instantiate them via some
other public class in the same packages as the first two singletons) or
both.

Either way, your first two singletons disappear and are replaced by the
(then) only singleton in the system, which might look like:

public class SystemSingleton {
    SystemSingleton systemSingleton = new SystemSingleton();
    ModelSingleton modelSingleton = null;
    private SystemSingleton(){};
    public static SystemSingleton getInstance{
       return systemSingleton;
    }

  public void setModelSingleton(ModelSingleton modelSingleton) {
     this.modelSingleton  = modelSingleton;
  }

  public ModelSingleton getModelSingleton() {
     return modelSingleton;
  }
}

Of course you have to guarantee a phased start-up, to ensure that the
singletons register themselves before clients want to use them ...

.ed

--
www.EdmundKirwan.com - Home of The Fractal Class Composition.

Download Fractality, free Java code analyzer:
www.EdmundKirwan.com/servlet/fractal/frac-page130.html


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.