0

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.

Community
  • 1
  • 1
Nishant Kelkar
  • 412
  • 1
  • 4
  • 20
  • "I was thinking having a Singleton is overkill"- no! having a Singleton is not an overkill, you going out of your way to avoid creating a singleton is an overkill. – Nir Alfasi Jul 19 '14 at 06:26
  • Enumeration is the most flexible and reliable way to create singleton, since it was created by experienced developers with huge knowledge in any issues. – ferrerverck Jul 19 '14 at 06:43
  • @alfasin By overkill, I meant that what Singletons offer me is a much stricter bound than what I need (Singletons leave no room for flexibility -- I want that too, except for the .properties file WITH ability to perform tests) – Nishant Kelkar Jul 20 '14 at 05:34
  • @NishantKelkar you don't have to implement a singleton using static methods, there are other implementation. The safest and most recommended way to implement a singleton since Java 5 is by using an `enum`. – Nir Alfasi Jul 20 '14 at 07:07

1 Answers1

2

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.

William F. Jameson
  • 1,833
  • 9
  • 14
  • @WilliamFJameson Aah, the requirement that I need to set the properties filename only once fits nicely around the immutable POJO idea. I think half of the problems that emerge around this border between Singletons, static classes and normal classes is over-estimation of object creation overhead. I guess it's not too big of a deal as I've heard people make it sound. Would you agree/disagree? – Nishant Kelkar Jul 20 '14 at 17:12
  • Object creation is one of the most aggressively optimized operations on the JVM: it costs literally several CPU cycles. Unless you are up to creating millions of objects per second, you should not worry about it. – William F. Jameson Jul 20 '14 at 17:28