Search code examples
javadesign-patternssingletonglobal-state

Alternative To Singleton Util Class


So I have a class like so:

public class HBaseUtil {
    private final String fileName = "hbase.properties";
    private Configuration config;

    private HBaseUtil() {
       try {
         config = new PropertiesConfiguration(fileName);
       } catch (ConfigurationException e) {
         // some exception handling logging
       }
    }

    // now some getters pulling data out of the config object

    public static String getProperty(String fieldKeyName) {...}

    public static String getColumnFamily(String fieldName) {...}

    // ... some more getters

    // NO setters (thus making this a read-only class)
}

Thus, basically I have for myself a Singleton class, that the very first time that it is put to use, sets up a configuration object, and then simply keeps listening for get calls. There are a number of problems with this class:

  1. Unit testing the static methods within class HBaseUtil becomes difficult because of a tight-knit coupling between the Singleton and the configurations file.
  2. What I really want is me being able to supply the filename/filename+path to the class so that it can go in there, read the configuration properties from that file and offer them to incoming read requests. One important note here though: I need this flexibility in specifying the properties file ONLY ONCE per JVM launch. So I certainly don't need to maintain state.

Here is what I was able to come up with: Instead of a Singleton, I have a normal class with all static methods and no explicit constructor defined.

public class HBaseUtil {
    // directly start with getters
    public static String getProperty(Configuration config, String fieldKeyName) {...}

    public static String getColumnFamily(Configuration config, String fieldKeyName) {...}

    // ...and so on
}

And then, instead of using the class in my other code like such:

HBaseUtil.getProperty(String fieldKeyName)

I'd use it like so:

Configuration externalConfig = new PropertiesConfiguration("my-custom-hbase.properties");

HbaseUtil.getProperty(externalConfig, fieldKeyName) 

My questions:

  1. Am I even thinking in the right direction? My requirement is to have the flexibility in the class only ONCE per JVM. All that needs to be configurable in my project for this, is the location/contents of the HBase .properties file. I was thinking having a Singleton is overkill for this requirement.
  2. What other better approaches are there for my requirement (stated in above point)?

Thanks!

Note: I've read this StackOverflow discussion, but now it's gotten me even more confused.


Solution

  • You should avoid all static methods and instead design a class which does not mandate its lifecycle: it can be a typical immutable POJO with a public constructor.

    Then, when you need it as a singleton, use it as a singleton. For testing, use it in some other way.

    Usually, dependency injection is the preferred avenue to solve these problems: instead of hard-coding a pulling mechanism for your configuration object, you have the object delivered to any class which needs it. Then you can decide late what bean you will deliver.

    Since you are probably not using Spring (otherwise dependency injection would be your default), consider using Guice, which is a very lightweight and non-intrusive approach to dependency injection.