Reputation: 6638
I chose to take properties file for customization of some settings. I use the following code to make a Properties Object available in a class
Properties defaultProps = new Properties();
try {
FileInputStream in = new FileInputStream("custom.properties");
defaultProps.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
Do I have to add this to every class? Probably not because then every class would open a stream to this file.
But I'm not sure how to handle this properly.
Should I make a class MyProperties
and instantiate it in whatever class needs properties?
Thanks in advance!
Upvotes: 11
Views: 19659
Reputation: 42899
If you only need one instance of your properties class you can use the singleton (anti?)-pattern.
It would look like a class like this:
public class MyProperties extends Properties {
private static MyProperties instance = null;
private MyProperties() {
}
public static MyProperties getInstance() {
if (instance == null) {
try {
instance = new MyProperties();
FileInputStream in = new FileInputStream("custom.properties");
instance.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return instance;
}
}
Upvotes: 3
Reputation: 2168
Rather than loading properties in every class. Load it somewhere around main() and pass it to other classes via their constructors.
Don't share them globally. - Difficult to test - Against the abstraction (Global access, DAO can access user settings. it should be prevented by passing only what it needs.. not everything) - Classes lie what they need
Upvotes: 0
Reputation: 9555
Since this information is static across all instances, I recommend implementing the Properties
class as a singleton. By using the static
initialization block method, you can have it load the file automatically when the program starts up.
public class Properties {
static {
try {
FileInputStream in = new FileInputStream("custom.properties");
load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
protected static void load(FileInputStream in) {
// existing load functionality here
}
}
You are still going to need an internal storage mechanism and accessor mechanism. These should also be marked static
.
Upvotes: 0
Reputation: 14558
Why not use a static ResourceBundle ?
static final ResourceBundle myResources =
ResourceBundle.getBundle("MyResources", currentLocale);
Upvotes: 1
Reputation: 116266
Once you initialized defaultProps
, you can make its contents available to other objects in your app e.g. via a public static accessor method, e.g.:
public class Config {
private static Properties defaultProps = new Properties();
static {
try {
FileInputStream in = new FileInputStream("custom.properties");
defaultProps.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getProperty(String key) {
return defaultProps.getProperty(key);
}
}
This is the simplest approach, however it creates an extra dependency which makes unit testing harder (unless you provide a method in Config
to set a mock property object for unit testing).
An alternative is to inject defaultProps
(or individual configuration values from it) into each object which needs it. However, this may mean you need to add extra parameter(s) to lots of methods if your call hierarchies are deep.
Upvotes: 14
Reputation: 46422
This is a special case of making anything available globally. Using static methods is quite bad. A better but bad solution is using the sigleton pattern. Testing is the greatest problem here. IMHO, the best way is using Dependency injection, although it may be an overkill for small applications.
Upvotes: 0
Reputation: 23629
Load the properties once using and store the Properties somewheres that others classes can pull from. If that is a MyProperties class that references a static variable somewhere that is fine.
Upvotes: 0
Reputation: 244
There's too little information to determine what the best way to handle this would be. You may want to expose it using an accessor, or pass it into each class that requires it. Alternatively, you may pull out the properties that each class needs and pass their values into the class's constructor.
Upvotes: 0