mardi 18 juillet 2017

Global mapping in the Java application

I wonder what is the best practice of having some global mapping in Java application?

Say I have a text file with the mapping:

key1:value1
key2:value2
...
keyN:valueN

The file is huge, and both keys and values are arbitrary, so I can't really use Enum.

In the Java application I'm going to instantiate a bunch of classes with keys as the input (note that the code is more adequate in reality, just trying to put it abstract and simple):

for(int i = 0; i < 10000; i++) {
    String key = magicallyGetArbitaryKey();
    SomeClass someClass = new SomeClass(key);
    //do stuff
}

and assign a property in the constructor based on the map lookup.

public class SomeClass {
    private String value;
    public void SomeClass(String key) {
       this.value = getValue(key);
    }

    private String getValue() {
    // what is the best way to implement this?
    }
}

I want my code to be simple and, what is important, testable. And avoid using frameworks such as Spring.

This is what I came up with so far: create a Holder class, which is simply a wrapper around the HashMap with the additional methods for initialization:

class MappingHolder {

private Map<String, String> keyValueMap = new HashMap();

public MappingHolder(String filePath){
    keyValueMap = ...; //init from the file
}

public MappingHolder(Map initMap) { //constructor useful for testing
    keyValueMap = initMap; 
}

public String get(String key) {
   return keyValueMap.get(key);
}

It seems to be obvious that I want to have only one instance of the mapping.

As far as I can see the options are:

  1. Have the MappingHolder#getValue as a static method

    public class SomeClass {
    ...
    private String getValue() {
       return MappingHolder.getValue()
    }
    
    
  2. Have the MappingHolder#getValue as an instance method, but make field of the type MappingHolder static in the SomeClass

    public class SomeClass {
    ...
    private static MappingHolder mappingHolder = new MappingHolder();
    private String getValue() {
       return mappingHolder.getValue();
    }
    
    
  3. Make the MapppingHolder a singleton.

    public class SomeClass {
    ...
    private MappingHolder mappingHolder = MappingHolder.getInstance();
    private String getValue() {
       return mappingHolder.getValue();
    }
    
    

Neither of this seems to me testable, having just JUnit and Mockito and not leveraging some more powerful mocking frameworks. Though I sucks in testing and maybe I am wrong.

So it would be great if one could recommend the approach, either how to develop further my own, or better one which I may be missing. Thanks!

Aucun commentaire:

Enregistrer un commentaire