tags:

views:

97

answers:

5

I'm at the point in my first real application where I am adding in the user settings. I'm using Java and being very OO (and trying to keep it that way) so here are my ideas:

  1. Load everything in the main() and pass it all 'down the line' to the required objects (array)
  2. Same as above, but just pass the object that contains the data down the line
  3. Load each individual setting as needed within the various classes.

I understand some of the basic pros and cons to each method (i.e. time vs. size) but I'm looking for some outside input as to what practices they've successfully used in the past.

+2  A: 

Since configuration / settings are typically loaded once (at startup; or maybe a few times during the program's runtime. In any way, we're not talking about a very frequent / time-consuming process), I would prefer simplicity over efficiency.

That rules out option number (3). Configuration-loading will be scattered all over the place.

I'm not entirely sure what the difference is between (1) and (2) in your list. Does (1) mean "passing discreet parameters" and (2) mean "passing an object containing the entire configuration"? If so, I'd prefer (2) over (1).

The rule of thumb here is that you should keep things simple and concentrated. The advantage of reading configuration in one place is that it gives you better control in case the source of the configuration changes at some point.

Isaac
+1  A: 

Use a SettingsManager class or something similar that is used to abstract getting all settings data. At each point in the code where you need a setting you query the SettingsManager class - something like:

int timeout = SettingsManager.GetSetting("TimeoutSetting");

You then delegate all of the logic for how settings are fetched to this single manager class, whose implementation you can change / optimize as needed. For instance, you could implement the SettingsManager to fetch settings from a config file, or a database, or some other data store, periodically refresh the settings, handle caching of settings that are expensive to retrieve, etc. The code using the settings remains blissfully unaware of all of these implementaton decisions.

For maximum flexibility you can use an interface instead of an actual class, and have different setting managers implement the interface: you can swap them in and out as needed at some central point without having to change the underlying code at all.

In .NET there is a fairly rich set of existing configuration classes (in the System.Configuration) namespace that provide this sort of thing, and it works out quite well.

I'm not sure of the Java equivalent, but it's a good pattern.

mtreit
You cannot string index in Java. You need a map.
Thorbjørn Ravn Andersen
Well, the code sample is essentially pseudo-code: the main idea is that you have something that centrally manages getting the settings. Anyway, I changed it to not use string indexing.
mtreit
In (standard) Java this is the Preferences API: http://download.oracle.com/javase/6/docs/technotes/guides/preferences/index.html
Carlos Heuberger
A: 

We have recently started using JSR-330 dependency injection (using Guice from SVN) and found that it was possible to read in a Properties file (or any other map) and bind it inside Guice in the module in the startup code so that the

@Inject @Named("key") String value

string was injected with the value corresponding to the key when that particular code was called. This is the most elegant way I have ever seen for solving this problem!

You do not have to haul configuration objects around your code or sprinkle all kinds of magic method calls in each and every corner of the code to get the values - you just mention to Guice you need it, and it is there.

Note: I've had a look at Guice, Weld (Seam-based) and Spring which all provide injection, because we want JSR-330 in our own code, and I like Guice the best currently. I think the reason is because Guice is the clearest in its bindings as opposed to the under-the-hood magic happening with Weld.

Thorbjørn Ravn Andersen
+1  A: 

Here is a tutorial on the Properties class. From the Javadocs (Properties):

The Properties class represents a persistent set of properties. The Properties can be saved to a stream or loaded from a stream. Each key and its corresponding value in the property list is a string.

A property list can contain another property list as its "defaults"; this second property list is searched if the property key is not found in the original property list.

The tutorial gives the following example instantiation for a typical usage:

    . . .
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();

// create application properties with default
Properties applicationProps = new Properties(defaultProps);

// now load properties from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
. . .

You could, of course, also roll your own system fairly directly using a file-based store and an XML or YAML parser. Good luck!

Joe
+1, since this is what a lot of apps do.
andersoj
Basically that is what I was leaning towards since I am using XML to store the data.
Glenn Nelson
You may want to look at the answer given by @andersoj as well, the Preferences class seems to be the "new way" to do this...
Joe
+4  A: 

Someone should stand up for the purported Java standard, the Preferences API... and it's most recent incarnation in JDK6. Edited to add, since the author seems to savvy XML, this is more appropriate than before. Thought I believe you can work XML juju with Properties too, should the spirit take you.

Related on SO: Preferences API vs. Apache solution, Is a master preferences class a good idea?

(well, that's about all the standing up I'm willing to do.)

andersoj
+1, this is probably the best way to do it in fact.
Joe
This is exactly what you want to do. Go with preferences. If you're not happy with the stock implementation, override it with your own. But the foundation is sound. This should be a simple service.
Will Hartung