0

My question is the same as this one except it is for Java, specifically applied to properties. Ideally I would like to create one instance of Properties, and call the methods from all of the classes without creating new instances. I would also want to read from a single instance of properties so I only have a single source of the truth.

I have read the API for Properties and it doesn't answer my question.

This question indicates I need to include the reference in the class constructor. Is there a better way??

dazz
  • 97
  • 1
  • 10
  • What *exactly* is your question? Your first link just points to the Properties tutorial and not an actual question. – sruetti Sep 13 '17 at 07:22
  • What do you want to use the Properties for? If you just want to *read* configuration values, [System Properties](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html) might be the easiest way to pass values to your program. – sruetti Sep 13 '17 at 08:21

2 Answers2

0

Let's take the system properties as example. In this implementation http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java#System.getProperty%28java.lang.String%29, the properties are just stored in a static class attribute. Either make this attribute public or create public accessor methods. Short answer: just make it static.

You can initialize static data with static initializers, if things get a little bit more complex. (https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)

Mick
  • 877
  • 7
  • 15
  • So if I create an instance of Properties in main called props, then call a class that while doing its job "gets" one of the properties, how will a static method know that I am referring to props? My (limited) understanding is that static methods can't create or call a dynamic object. The only way I can see static methods working would be to get the property from a file and not from an Property object. – dazz Sep 13 '17 at 07:33
  • I found this question https://stackoverflow.com/questions/18125106/make-global-instance-of-class-java indicating that Singletons might be the solution but not fully OOPs. – dazz Sep 13 '17 at 07:39
  • @dazz: Singletons do have drawbacks and *might* be a code smell. But depending on your environment, this discussion might also be a bit academic... see https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons, [The Good, the Bad and the Singleton](http://rcardin.github.io/design/programming/2015/07/03/the-good-the-bad-and-the-singleton.html), or [Singletons Are Evil](http://wiki.c2.com/?SingletonsAreEvil) for more information and to judge how these drawbacks apply to your situation. – sruetti Sep 13 '17 at 08:51
  • I also found this article https://www.javaworld.com/article/2073352/core-java/simply-singleton.html which both promotes and warns against using singletons. What appears to be missing from Java (based on my limited knowledge) is a means of sending signals between objects. So if Class A creates a property read instance, then Class B changes the property file, there should be a way of Class B signaling to other objects (Class A) that they need to update their property instance. Singletons seem to be a flawed attempt to solve this problem. Is there a better way? – dazz Sep 14 '17 at 04:14
  • @Mick I read the code but I can't figure out where the instance of Properties would be created to allow the statement "return props.getProperty(key);" to work. I presume this would have been in the constructor for this class. If so, then there would be the problem of multiple instances (one per user class) of properties. – dazz Sep 14 '17 at 04:23
  • @dazz: I added a link about how to init static data. – Mick Sep 14 '17 at 09:22
  • I found this article https://logging.apache.org/log4j/2.x/manual/configuration.html#ChainsawSupport which states in part " Log4j provides the ability to 'advertise' appender configuration details for all file-based appenders as well as socket-based appenders.Chainsaw and other external systems can discover these advertisements and use that information to intelligently process the log file. " This method looks like the better way if it can be extended for general use. – dazz Sep 16 '17 at 11:13
0

The fisrt link, "this one" is a link to the Oracle documentation...

If you want to load your properties only once, you should use the singleton pattern. But be carefull that this pattern can be an anti-pattern and may make your unit tests more complex.

To avoid those drawbacks it is better to pass the reference to your properties via a constructor.

/* This is your singleton. It takes care of loading the properties only once and can delegate access method  to it */
public class Configuration {
   private static Configuration instance; // created only once
   public static getInstance() {
      instance = // Read the Singelton pattern to create it only once   
   }


   private Properties properties; // loaded only once

   public String get(String key) {
       return properties.getProperty(key);
   }

}

public class Component {
    private final Configuration cfg;
    public Component (Configuration cfg) {
        this.cfg = cfg;
    }
}

public class StarterOrDiContainer {
    // ..
    Component component = new Component(cfg.getInstance());
}
gervais.b
  • 1,964
  • 1
  • 14
  • 36