views:

410

answers:

9

I am working in Java on a fairly large project. My question is about how to best structure the set of Properties for my application.

Approach 1: Have some static Properties object that's accessible by every class. (Disadvantages: then, some classes lose their generality should they be taken out of the context of the application; they also require explicit calls to some static object that is located in a different class and may in the future disappear; it just doesn't feel right, am I wrong?)

Approach 2: Have the Properties be instantiated by the main class and handed down to the other application classes. (Disadvantages: you end up passing a pointer to the Properties object to almost every class and it seems to become very redundant and cumbersome; I don't like it.)

Any suggestions?

+7  A: 

I like using Spring dependency injection for many of the properties. You can treat your application like building blocks and inject the properties directly into the component that needs them. This preserves (encourages) encapsulation. Then, you assemble your components together and create the "main class".

A nice side effect of the dependency injection is that your code should be more easily testable.

Alex B
Much more preferable since it doesn't require a generic Properties reference at all. It is specific to the classes needs.
Robin
+1  A: 

Sounds like you need a configuration manager component. It would be found via some sort of service locator, which could be as simple as ConfigurationManagerClass.instance(). This would encapsulate all that fun. Or you could use a dependency injection framework like Spring.

Much depends on how components find each other in your architecture. If your other components are being passed around as references, do that. Just be consistent.

sblundy
A: 

I usually go for a singleton object that resides in a common project and contains a hashtable of itself keyed on namespace, resulting in a properties class for each.

Dependency injection is also a nice way of doing it.

Rob Stevenson-Leggett
+1  A: 

Actually, approach 2 works really well.

I tried using a Singleton properties object on a recent project. Then, when it came time to add features, I need to revise the Singleton, and regretted having to locate every place where I used MySingleton.getInstance().

Approach 2 of passing a global information object through your various constructors is easier to control.

Using an explicit setter helps, too.

class MyConfig extends Properties {...}

class SomeClass {
    MyConfig theConfig;
    public void setConfi( MyConfig c ) {
        theConfig= c;
    }
    ...
}

It works well, and you'll be happy that you tightly controlled precisely which classes actually need configuration information.

S.Lott
I think MyConfig should contain a Properties object rather than extend it. But it would work either way.
ScArcher2
Approach 2 is the way to go. And may I suggest using [Guice](http://code.google.com/p/google-guice/) to manage dependency.
albertb
I don't see how this is better. If you change MyConfig (as you did the singleton), you still have the same refactoring issue (dependent on what the change is of course) of making the changes in all places it is referenced.
Robin
@Robin: Not if you're creating a proper polymorphic subclass of MyConfig. Then there's no change except to the initial construction of MyOtherConfig, a subclass of MyConfig.
S.Lott
+2  A: 

If the properties are needed by a lot of classes, I would go for approach 1. Or perhaps a variant in which you use the Singleton design pattern instead of all static methods. This means that you don't have to keep passing some properties object around. On the other hand, if only a few classes need these properties, you might choose approach 2, for the reasons you mentioned. You might also want to ask yourself how likely it is that the classes you write are actually going to be reused and if so, how much of a problem it is to also reuse the properties object. If reuse is not likely, don't bother with it now and choose the solution that is the simplest for the current situation.

Daan
A: 

I feel more comfortable when I have a static pointer to my in-memory properties. some times you want to reload properties in runtime, or other functionality that is easier to implement with a static reference.

just remember that no class is an island. a reusable class can have a client class to keep the core free of the singletone reference.

you can also use interfaces, just try not to overdo it.

Amir Arad
A: 

Approache 2 is defenetly better.

Anyway, you should not let other class search through config object. You should injet config taken in the config object ouside the object.

Take a look at apache commons configuration for help with configuration Impl.

So in the main() you could have

MyObject mobj = new MyObject();
mobj.setLookupDelay(appConfig.getMyObjectLookupDelay);
mobj.setTrackerName(appConfig.getMyObjectTrackerName);

Instead of

MyObject mobj = new MyObject();
mobj.setConfig(appConfig);

where appConfig is a wrapper around the apache configuration library that do all the lookup of the value base on the name of the value in a config file.

this way your object become very easily testable.

Frederic Morin
+1  A: 

If you are looking for something quick you can use the System properties, they are available to all classes. You can store a String value or if you need to store a list of 'stuff' you can use the System.Properties() method. This returns a 'Properties' object which is a HashTable. You can then store what ever you want into the table. It's not pretty but it's a quick way to have global properties. YMMV

Javamann
A: 

Haven't done Java for a while, but can't you just put your properties into the java.lang.System properties? This way you can access the values from everywhere and avoid having a "global" property class.