在java中增加工厂模式 [英] augment the factory pattern in java
问题描述
我试图使用工厂模式创建一个QuestionTypeFactory,其中实例化的类将像MultipleChoice,TrueFalseQuestion等。
I am trying to use a factory pattern to create a QuestionTypeFactory where the instantiated classes will be like MultipleChoice, TrueFalseQuestion etc.
出厂代码看起来像这样
class QuestionFactory {
public enum QuestionType {
TrueFalse,
MultipleChoice,
Essay
}
public static Question createQuestion(QuestionType quesType) {
switch (quesType) {
case TrueFalse:
return new TrueFalseQuestion();
case MultipleChoice:
return new MultipleChoiceQuestion();
case Essay:
return new EssayQuestion();
}
throw new IllegalArgumentException("Not recognized.");
}
}
现在可以正常工作。如果我想添加另一个问题类型,我将需要修改工厂类,我不想这样做。
This works ok for now. If I want to add another question type I will need to modify the factory class and I do not want to do that.
我如何设置它,以便每个问题类都向Factory注册,这样当我添加一个新的问题类型时,我不必更改代码工厂?我对java有点新鲜感,不知道该怎么做。
How can I set it up so that each question class registers itself with the Factory so that when I add a new question type, I do not have to change the code for the factory? I am a bit new to java and am not sure how to do this.
附加信息
所有问题类都实现了一个IQuestion界面。我正在寻找一种方法来实现一个方法,如
All the question classes implement an IQuestion interface. I am looking for a way to implement a method like
public static void registerType(QuestionType quesType, Class<IQuestion> ques)
所以我可以从我的类的静态块调用这个方法,这样当我添加一个新的问题键入,我不必在问题工厂中更改或添加任何代码。我知道我将不得不改变当前的实现,使其成为通用的。我不知道我上面写的方法在语法上是不正确的,但它显示了我想要的概念。
so that I can call this method from a static block from my classes so that when I add a new question type, I will not have to change or add any code in the Question Factory. I know I would have to change the current implementation to make it generic. I am not sure the method that I wrote above is correct in terms of its arguments syntactically or not but it shows what I want in concept.
推荐答案
您可以通过Reflection API(即 Class
thingy)使用您显示的注册方法来执行此操作。
You can probably do that with the register method you've shown, through the Reflection API (that Class
thingy).
我不太熟练地使用Java Reflection编写更有用的答案,但是如果你寻找一些 getConstructor
方法或者你可能会得到的东西
I am not proficient enough with Java Reflection to write a more helpful answer, but if you look for some getConstructor
method or something you'll probably get there.
要调用该方法,您应该执行以下操作(请注意 .class
语法):
To call that method you should do something like (note the .class
syntax):
QuestionFactory.registerType(QuestionType.TrueFalse, TrueFalseQuestion.class);
编辑啊,无论如何,我有时间调查。尝试这样:
EDIT Ah, whatever, I have the time to investigate. Try this:
public class QuestionFactory {
static final Map<QuestionType, Constructor<? extends Question>> map =
new HashMap<QuestionType, Class<? extends Question>>();
public static void registerType(QuestionType quesType, Class<? extends Question> ques) {
map.put(quesType, ques.getConstructor());
}
public static Question createQuestion(QuestionType quesType) {
return map.get(quesType).newInstance();
}
}
我没有编译这个,但它应该工作,或者至少指导你正确的方向。为了这个工作,Question实现必须有一个没有参数的构造函数。
I haven't compiled this, but it should work, or at least guide you in the right direction. For this to work the Question implementations must have a constructor without arguments.
因为你使用一个静态工厂(也就是面向对象的全局变量),你可以提出问题注册自己的静态初始化程序。
Because you're using a static factory (aka, object-oriented global variables) you can make questions register themselves in their static initializer.
public class TrueFalseQuestion implements Question {
static {
QuestionFactory.registerType(QuestionType.TrueFalse, TrueFalseQuestion.class);
}
// Whatever else goes here
}
这篇关于在java中增加工厂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!