To register the TrueFalseQuestion
class with the factory, its static initializer needs to be called. To execute the static initializer of the TrueFalseQuestion
class, the class needs to either be referenced or it needs to be loaded by reflection before QuestionFactory.map.size()
is called. If you want to leave the main
method untouched, you have to reference it or load it by reflection in the QuestionFactory
static initializer. I don't think this is a good idea, but I'll just answer your question :) If you don't mind the QuestionFactory
knowing about all classes that implement Question
to construct them, you can just reference them directly or load them through reflection. Something like:
public class QuestionFactory {
static final HashMap<String, String > map = new HashMap<String,String>();
static {
this.getClassLoader().loadClass("TrueFalseQuestion");
this.getClassLoader().loadClass("AnotherTypeOfQuestion"); // etc.
}
public static void registerType(String questionName, String ques ) {
map.put(questionName, ques);
}
}
Make sure map
's declaration and construction is before the static
block. If you don't want QuestionFactory
to have any knowledge of the implementations of Question
, you'll have to list them in a configuration file that gets loaded by QuestionFactory
. The only other (possibly insane) way I could think to do it, would be to look through the entire classpath for classes that implement Question
:) That might work better if all classes that implemented Question
were required to belong to the same package -- NOTE: I am not endorsing this solution ;)
The reason I don't think doing any of this in the QuestionFactory
static initializer is because classes like TrueFalseQuestion
have their own static initializer that calls into QuestionFactory
, which at that point is an incompletely constructed object, which is just asking for trouble. Having a configuration file that simply lists the classes that you want QuestionFactory
to know how to construct, then registering them in its constructor is a fine solution, but it would mean changing your main
method.