0

I'm writing a setup routine with several configuration parameters (for now, could be int, double, or String). In order to avoid long method signatures, I'd like to create a data structure to store these parameters. The main setup routine calls several methods/factories, each with their own set of required parameters, and I'd like to only pass the relevant piece of the data structure to each routine.

My initial thought was to use some kind of recursive/tree dictionary-like structure, where String keys could be associated with either a value, or a subtree that behaves exactly like the top-level tree.

A rough example of what I'm trying to do follows:

public class A {
  // some common methods here
}

public class A1 extends A {
  public A1(int x, double y) {
    // do stuff
  }
}

public class A2 extends A {
  public A2(double z) {
    // do stuff
  }
}

public A SetupA(ConfigOptions opts) {
  if (opts.get("typeA").equals("A1")) {
    return SetupA1(opts.get("A1opts"));
  } else {
    return SetupA2(opts.get("A2opts"));
  }
}

public A1 SetupA1(ConfigOptions A1opts) {
  return new A1(A1opts.get("x"), A1opts.get("y"));
}

public A2 SetupA2(ConfigOptions A2opts) {
  return new A2(A2opts.get("z"));
}

When I fill the ConfigOptions structure, I'd like to have a character, e.g. :, that separates levels of the tree. I.e. for the example above, I could specify that I want an A2 object with z = 1.0 something like this:

opts.set("typeA", "A2");
opts.set("A2opts:z", 1.0);

I know that what I've just laid out won't work as written since it's not type-safe. What modifications to the interface, and/or what implementation techniques could I consider that would allow me to accomplish my objectives?

Notes:

  • The setup routine has a relatively small one-time cost. Therefore readability and a convenient interface is a much higher priority for me than speed.
  • This is a learning project for me, so I'm looking for a solution that doesn't depend on external libraries or built-in collection classes.
  • Error checking does not need to be considered by the data structure, since it will be handled by the routines that receive the parameters.
astay13
  • 6,857
  • 10
  • 41
  • 56
  • The `Map` should be sufficent. – Nikolas Charalambidis Jul 17 '18 at 19:19
  • @Nikolas, as I noted above, I'd like to do it without using built-in collection classes. – astay13 Jul 17 '18 at 19:43
  • Have you considered YAML for your configuration? You can use existing YAML parser. If you want to learn, you can check it's implementation. – Pavel Molchanov Jul 17 '18 at 19:43
  • @PavelMolchanov, I wasn't aware of YAML, but it looks interesting on first glance. For this question though, I'm more concerned with the internal representation. i.e. after calling the YAML parser to read the file, I need to somehow store the config options internally – astay13 Jul 17 '18 at 20:01
  • For YAML you can create a data model as POJO classes and annotate your model. Then use the parser to parse the YAML and populate your model. Example: https://dzone.com/articles/read-yaml-in-java-with-jackson or this: https://stackoverflow.com/questions/25796637/parse-a-yaml-file – Pavel Molchanov Jul 17 '18 at 20:19
  • @PavelMolchanov, while that definitely sounds like a good solution, I was hoping to separate the input format from the internal representation of the configuration. In other words, I would like to have a data structure for the configuration parameters that does not depend on the input format in any way. That way I won't have to change the initialization routine every time I need to read from a different input format. – astay13 Jul 18 '18 at 15:22
  • Then you need a key-value map. Something like Map. Object can be anything (String, Integer, Map. Then you can define strategies for parsing your value parameters. – Pavel Molchanov Jul 18 '18 at 18:57
  • @PavelMolchanov, I can imagine how to create something like Map, but I was hoping for a solution that doesn't break type-safety by using Object. – astay13 Jul 18 '18 at 21:56
  • Maybe Composite design pattern will help you: https://en.wikipedia.org/wiki/Composite_pattern – Pavel Molchanov Jul 18 '18 at 22:01
  • @astay13 Did you find a solution to this – kimathie Nov 18 '19 at 19:27
  • @kimathie, I ended up with a class that contained an `int`, `double`, and `String`, with unique methods to set/get each one, but where only one of them could be valid at a time. Kind of wasteful on space, but I preferred that to losing type-safety by casting to/from `Object`. Not a great solution but the best bad one I could find. – astay13 Nov 30 '19 at 05:53
  • @astay13 I get you – kimathie Mar 04 '20 at 05:34

0 Answers0