jnovacho jnovacho - 3 months ago 24
Java Question

Singleton class with parameter

I'm developing computer vision application and I will need Classifier class. This class will be immutable per run of application and it loads the trained data from disk on initialization. I want to ensure that whole program will have access to same trained data and I want to block reloading the from disk once they are loaded.

What I was considering was to use either static class or singleton. I'm not sure how to load data to static class, because the path to data file is not know at compile time - it will be program argument. So I was thinking of Singleton pattern, but there I don't know how to initialize it dynamically.

My idea was to use following:

class Singleton {
private static Singleton instance;
private Singleton() { ... }
private static SomeDataObject data;

public static Singleton getInstance() {
if(instance == null)
instance = new Singleton();

return instance;
}

public static init(string dataPath){
if(data == null)
loadDataFromFile(dataPath)
}
}


This would not work, because I have no control which method will be called first.

I know the proper way would be to create the instance with data at the begining and pass it to all classes and methods which need it, but that's not really general solution. I can keep track of all calls to Classifier in my own code, but if I would make the code as API, this would be a problem.

In short how to initialize singleton at runtime?

Answer

I don't think (exactly) what you want to do would work.

The below would work:

public static void main(String[] args)
{
  Singleton.init("somepath");
  ...
  Singleton.getInstance().doingStuff();
  ...
}

A better implementation may be: (which would cause a NullPointerException if you try to use it without calling init first) (not really Singleton any more though)

private static Singleton instance;
private SomeDataObject data;

private Singleton(String path) { loadDataFromFile(path); ... }

public static Singleton getInstance() {
   return instance;
}

public static init(String dataPath){
   instance = new Singleton(dataPath);
}

Then there's: (possible bad coding practice aside)

class Main
{
  public static void main(String[] args)
  {
    Singleton.currentPath = "somepath";
    ...
  }
}

class Singleton
{
  public static String currentPath = null;
  private static Singleton instance;
  private SomeDataObject data;

  private Singleton(String path) { loadDataFromFile(path); ... }

  public static Singleton getInstance() {
     if(instance == null && currentPath != null)
        instance = new Singleton(currentPath);
     return instance;
  }
}

which I suppose doesn't really solve much.