Initializing Singletons

J

Jason Cavett

I'm curious - is it possible (and if so, how) to initialize a
Singleton class when the class used for initialization must also get
an instance of the Singleton class?

Here's a pseudocode example to make that more clear...

class SingletonClass {

private SingletonClass() {
ConfigFileReader reader = new ConfigFileReader();
reader.read();
}

// other singleton stuff
}

class ConfigFileReader {

public ConfigFileReader() {
// do stuff
}

public void read() {
// read in the config file and get the appropriate information
SingletonClass.getInstance().setValues(...);
}
}


I don't *think* what I want to do is possible. But, if it is, I'm not
sure how to do it. Any insight would be appreciated.


Thanks
 
T

Tom Anderson

I'm curious - is it possible (and if so, how) to initialize a Singleton
class when the class used for initialization must also get an instance
of the Singleton class?

The way you want to do it, no.
Here's a pseudocode example to make that more clear...

class SingletonClass {

private SingletonClass() {
ConfigFileReader reader = new ConfigFileReader();
reader.read();
}

// other singleton stuff
}

class ConfigFileReader {

public ConfigFileReader() {
// do stuff
}

public void read() {
// read in the config file and get the appropriate information
SingletonClass.getInstance().setValues(...);
}
}


I don't *think* what I want to do is possible. But, if it is, I'm not
sure how to do it. Any insight would be appreciated.

Are you writing ConfigFileReader? If so, make read take a SingletonClass
as a parameter:

class ConfigFileReader {
public void read(SingletonClass singleton) {
singleton.setValues(...) ;
}
}

That's probably the easiest way.

Another thing you could do would be to initialise the singleton instance a
bit differently, so that getInstance becomes usable (FSVO 'usable') before
the constructor finishes:

class SingletonClass {
private static SingletonClass INSTANCE ;
static {
new SingletonClass() ;
}
public SingletonClass()
{
INSTANCE = this ;
ConfigFileReader reader = new ConfigFileReader() ;
reader.read() ;
}
}

But that's fairly sick. It also means that you're putting an uninitialised
object in the INSTANCE field, which is potentially risky.

tom
 
D

Daniel Pitts

Jason said:
I'm curious - is it possible (and if so, how) to initialize a
Singleton class when the class used for initialization must also get
an instance of the Singleton class?

Here's a pseudocode example to make that more clear...

class SingletonClass {

private SingletonClass() {
ConfigFileReader reader = new ConfigFileReader();
reader.read();
}

// other singleton stuff
}

class ConfigFileReader {

public ConfigFileReader() {
// do stuff
}

public void read() {
// read in the config file and get the appropriate information
SingletonClass.getInstance().setValues(...);
}
}


I don't *think* what I want to do is possible. But, if it is, I'm not
sure how to do it. Any insight would be appreciated.


Thanks

Without seeing getInstance, I can't be certain, but it looks like you'll
get infinite recursion... It would be better to use dependency injection
instead... If you absolutely *need* to use singleton (one of the most
abused patterns, BTW), you can try this:

public static SingletonClass getInstance() {
if (instance == null) {
instance = new SingletonClass();
ConfigFileReader config = new ConfigFileReader(instance);
config.read();
}
return instance;
}

SingletonClass() now should do nothing, or at least only construction
related activities.

getInstance() will never return an uninitialized instance.

ConfigFileReader gets an explicit instance to read into. Much more
flexible for unit testing, etc...

In an ideal application, for every class that needed access to
SingletonClass, you would have a setSingletonInstance(...) method, and
use an injection container such as Guice or Spring (to name only two).

Hope this all helps.
Daniel.
 
M

Mike Schilling

Tom Anderson said:
The way you want to do it, no.


Are you writing ConfigFileReader? If so, make read take a SingletonClass
as a parameter:

class ConfigFileReader {
public void read(SingletonClass singleton) {
singleton.setValues(...) ;
}
}

That's probably the easiest way.

Or, if that's (for some reason) not possible, have two classes: the actual
singleton and the one the config reader creates.

class SingletonClass {

private SingletonClass() {
ConfigFileReader reader = new ConfigFileReader();
reader.read();
copyStuffFrom(PersistentSingletonClass.getInstance());
}
// other singleton stuff
}

class PersistentSingletonClass {
// getters, setters, getInstance() etc.
}

class ConfigFileReader {
public ConfigFileReader() {
// do stuff
}
public void read() {
// read in the config file and get the appropriate information
PersistentSingletonClass.getInstance().setValues(...);
}
 
J

Jason Cavett

Without seeing getInstance, I can't be certain, but it looks like you'll
get infinite recursion... It would be better to use dependency injection
instead...  If you absolutely *need* to use singleton (one of the most
abused patterns, BTW), you can try this:

public static SingletonClass getInstance() {
    if (instance == null) {
       instance = new SingletonClass();
       ConfigFileReader config = new ConfigFileReader(instance);
       config.read();
    }
    return instance;

}

SingletonClass() now should do nothing, or at least only construction
related activities.

getInstance() will never return an uninitialized instance.

ConfigFileReader gets an explicit instance to read into. Much more
flexible for unit testing, etc...

In an ideal application, for every class that needed access to
SingletonClass, you would have a setSingletonInstance(...) method, and
use an injection container such as Guice or Spring (to name only two).

Hope this all helps.
Daniel.

"If you absolutely *need* to use singleton (one of the most abused
patterns, BTW)"

I have my own opinions on this, but I'm curious - when *should* you
use a singleton pattern (in your opinion)? I'm not trying to start a
flame war, but, being a software engineer, I like seeing other
people's viewpoints on the matter.

Either way, I did get it to work. Thanks for the help.
 
D

Daniel Pitts

Jason said:
"If you absolutely *need* to use singleton (one of the most abused
patterns, BTW)"

I have my own opinions on this, but I'm curious - when *should* you
use a singleton pattern (in your opinion)? I'm not trying to start a
flame war, but, being a software engineer, I like seeing other
people's viewpoints on the matter.

Either way, I did get it to work. Thanks for the help.
Actually, the pattern that is abused is the "static" singleton. The
framework for your application should instantiate one instance and pass
it where it needs to go. This is appropriate for a lot of objects that
should be accessible "system wide". Dependency Injection is exclusive
with regards to Singletons, and I think a lot of people would be happier
if they mixed to two appropriately :)

As far as appropriateness for static singletons, I can't think of any
OTTOMH.
 
O

Owen Jacobson

Actually, the pattern that is abused is the "static" singleton.  The
framework for your application should instantiate one instance and pass
it where it needs to go. This is appropriate for a lot of objects that
should be accessible "system wide".  Dependency Injection is exclusive
with regards to Singletons, and I think a lot of people would be happier
if they mixed to two appropriately :)

As far as appropriateness for static singletons, I can't think of any
OTTOMH.

java.lang.Runtime is a reasonable example of something that both is
and should remain a singleton: it's abstract, the concrete instance
represents the JVM in which the current code is running, and (absent
tools like Terracotta) code is only *ever* running in a single JVM at
a time. I would've said "standard output should be a singleton",
except that I've written code for Unix systems where there were
multiple handles that all referred to standard output, so I see no
reason to forbid it. :)

-o
 

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

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top