I'm aiming to create a set of objects, each of which has a unique identifier. If an object already exists with that identifier, I want to use the existing object. Otherwise I want to create a new one. I'm trying not to use the word Singleton, because I know it's a dirty word here...
I can use a factory method:
// A map of existing nodes, for getInstance.
private static Map<String, MyClass> directory = new HashMap<String, MyClass>();
public static MyClass getInstance(String name) {
MyClass node = directory.get(name);
if(node == null) {
node == new MyClass(name);
}
return node;
}
Or equally, I could have a separate MyClassFactory method.
But I had intended to subclass MyClass:
public class MySubClass extends MyClass;
If I do no more, and invoke MySubClass.getInstance():
MyClass subclassObj = MySubClass.getInstance("new name");
... then subclassObj will be a plain MyClass, not a MySubClass.
Yet overriding getInstance() in every subclass seems hacky.
Is there a neat solution I'm missing?
That's the generalised version of the question. More specifics, since the answerers asked for them.
The program is for generating a directed graph of dependencies between nodes representing pieces of software. Subclasses include Java programs, Web Services, Stored SQL procedures, message-driven triggers, etc.
So each class "is-a" element in this network, and has methods to navigate and modify dependency relationships with other nodes. The difference between the subclasses will be the implementation of the populate()
method used to set up the object from the appropriate source.
Let's say the node named 'login.java' learns that it has a dependency on 'checkpasswd.sqlpl':
this.addDependency( NodeFactory.getInstance("checkpasswd.sqlpl"));
The issue is that the checkpasswd.sqlpl object may or may not already exist at this time.
Have you looked into Guice? Not sure if it would solve your problem exactly, but it acts as a generic factory and dependency injection container, and eliminates non-type safe String keys.