Singleton Pattern

M

Mark Jeffcoat

Chris Uppal said:
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).
 
L

Lionel

Chris Uppal wrote:
[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
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:

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.
 
K

Karl Uppiano

Mark Jeffcoat said:
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.
 
E

Ed

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
 
A

Andreas Leitgeb

Lionel said:
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.
 
C

Chris Uppal

Lionel said:
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 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
 
C

Chris Uppal

Arne said:
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.

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
 
C

Chris Uppal

Mark said:
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".
"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?

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
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).

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
 
L

Lionel

Chris said:
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).

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

Lionel.
 
M

Mark Jeffcoat

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).

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).
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.


Unsurprisingly, I agree with everything on this list.


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).

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.
 
C

Chris Uppal

Mark said:
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.

In this context, when I say "testing", I'm talking about constructing
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
 
R

RedGrittyBrick

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

<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.
 
A

andrewmcdonagh

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
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

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
 
A

andrewmcdonagh

On Dec 2, 12:08 pm, RedGrittyBrick <[email protected]>
wrote:

snipped...
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?


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);
 
R

RedGrittyBrick

andrewmcdonagh said:
On Dec 2, 12:08 pm, RedGrittyBrick <[email protected]>
wrote:

snipped...



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);

Thanks Andrew, I'll ponder that.
 
D

Daniel Pitts

RedGrittyBrick wrote:
[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.

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.
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
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?

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
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?

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.
 
C

Chris Uppal

RedGrittyBrick said:
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
 
C

Chris Uppal

andrewmcdonagh said:
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
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Chris said:
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.

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
 
C

Chris Uppal

Arne Vajhøj wrote:

[me:]
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.

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 ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Singleton Pattern 7
Singleton vs static 11
The Towers of Hanoi 3
Processing in Python help 0
Help with Singleton SafeConfigParser 4
Singleton Pattern or Rubbish? 2
Pattern suggestion 10
Singleton thread 1

Members online

Forum statistics

Threads
473,816
Messages
2,569,713
Members
45,502
Latest member
Andres34P

Latest Threads

Top