2

I have a class thats acts as a properties/configurations class. In addition to this, I also have a JSON file which contains the properties.

Right now, in my main class, I am instantiating a property object and then using the gson's fromJson method to read in the JSON file into this object. I am then passing this to my other classes so that they will be able to access the properties.

I want to refactor my design so that this property class will have static variables and methods, so that I don't have to instantiate it in order to access the properties.

I am wondering if this is possible using gson, or if this design is a good idea.

Thank you!

Carl Tan
  • 23
  • 3
  • 1
    How about **not**? What you're doing already is a better design. – John Bollinger Jul 05 '17 at 20:22
  • Passing in the properties object to the classes is ok? Sorry, I'm just not confident in my design patterns. – Carl Tan Jul 05 '17 at 20:23
  • Anything that relies on `static`, non-`final` data has bad code smell. And yes, that means that the data your objects rely upon for their computations should be actively provided to them, not dropped in a static storage location for them to retrieve. – John Bollinger Jul 05 '17 at 20:27

2 Answers2

0

You can use a static block in the property class, right? Initialize the fields there like you're doing now. Make them final to avoid race conditions.

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
-2

Feel free to ignore the people saying "don't do that". You know your code and requirements better than we do.

What you're looking for is called "reflection" in java. You can loop over your JSON key/value pairs, then look up the field using reflection, then set the field w/ the value.

This question has a good breakdown on how to do that.

Then use a static initialize block start your import function.

Good luck!

EDIT:

Some example code to show this isn't some crazy, complicated, unreadable horrible, no-good, very-bad idea that only James Gosling should ever attempt. :)

import java.lang.reflect.*;
import net.sf.json.*;

public class Test {
    public static String hello = null;

    static JSONObject readConfig() {
        // fake read a config file
        String settings = "{\"hello\": \"world\"}";
        JSONObject obj = (JSONObject)JSONSerializer.toJSON(settings);
        return obj;
    }

    static {
        // load config into static variables
        JSONObject config = Test.readConfig();
        for (Object key : config.keySet()) {
          String value = config.getString((String)key);
          try {
              Field field = Test.class.getDeclaredField((String)key);
              field.set(null, value);
              System.out.println("Set '"+ key +"' to '"+ value +"'.");
          } catch (Exception e) {
             System.err.println("Could not set unknown prop '"+ key +"' because "+ e +".");
          }
        }
    }

    public static void main(String[] args) {}
}

And it running:

$ javac -cp .:/usr/share/java/* Test.java 
$ java -cp .:/usr/share/java/* Test
Set 'hello' to 'world'.
keredson
  • 3,019
  • 1
  • 17
  • 20
  • 1
    That is the wrong answer for this questioner. This is a young padawan and you give a Luke Skywalker answer.. – Totoro Jul 05 '17 at 21:15
  • @Totoro respectfully I disagree. I know nothing about the programmer, I don't want to assume he's junior based only on his SO score. Plus his use case sounds legit. I would want compile-time checks of my config options too, but without having to manually tweak an import function for each. Good error checking should keep him safe/sane. Reflection isn't that complicated. :) – keredson Jul 05 '17 at 21:25
  • reflection is not hard, yes. but using it in such a way that it doesn't make your code insufferable, indecipherable or unusable by other teams is an art. And yes I prejudged him by his SO score. I would not use this technique casually w/out a demonstrable need for reflection. – Totoro Jul 07 '17 at 00:15
  • @Totoro added some sample code - I'd argue not insufferable, indecipherable or unusable. :) – keredson Jul 07 '17 at 15:47