增强java中的工厂模式
我正在尝试使用工厂模式来创建一个 QuestionTypeFactory,其中实例化的类将类似于 MultipleChoice、TrueFalseQuestion 等。
工厂代码看起来像这样,
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.");
}
}
目前可以正常工作。如果我想添加另一个问题类型,我将需要修改工厂类,但我不想这样做。
我如何设置它以便每个问题类都向工厂注册自己,以便当我添加新问题类型时,我不必更改工厂的代码?我对java有点陌生,不知道如何做到这一点。
编辑
附加信息
所有问题类都实现 IQuestion 接口。我正在寻找一种方法来实现这样的方法,
public static void registerType(QuestionType quesType, Class<IQuestion> ques)
以便我可以从类中的静态块调用此方法,这样当我添加新的问题类型时,我就不必在问题工厂中更改或添加任何代码。我知道我必须更改当前的实现以使其通用。我不确定我上面写的方法在语法上的参数是否正确,但它显示了我想要的概念。
I am trying to use a factory pattern to create a QuestionTypeFactory where the instantiated classes will be like MultipleChoice, TrueFalseQuestion etc.
The factory code looks something like this
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.
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.
Edit
Additional Information
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您也许可以通过 Reflection API(
Class
的东西)使用您所展示的 register 方法来做到这一点。我对 Java Reflection 不够精通,无法编写更有用的答案,但如果您寻找一些
getConstructor
方法或其他方法,您可能会找到答案。要调用该方法,您应该执行类似的操作(请注意
.class
语法):编辑 啊,无论如何,我有时间进行调查。试试这个:
我还没有编译这个,但它应该可以工作,或者至少引导您走向正确的方向。为此,问题实现必须有一个不带参数的构造函数。
因为您使用的是静态工厂(又名面向对象的全局变量),所以您可以使问题在其 静态初始值设定项。
You can probably do that with the register method you've shown, through the Reflection API (that
Class
thingy).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.To call that method you should do something like (note the
.class
syntax):EDIT Ah, whatever, I have the time to investigate. Try this:
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.
一种可能性:
当然,这摆脱了工厂并假设您的所有问题都有无参数构造函数,但据我所知,它涵盖了上面代码草图的所有情况。如果特定类的构造更复杂,您始终可以设置如下内容:
One possibility:
Of course, this gets rid of the factory and assumes all your questions have no-args constructors, but as far as I can tell, it covers all the cases of the code sketch above. If construction for the particularly classes is more complicated, you can always setup something like:
我很确定您只想在枚举类型上创建一个方法,该方法将返回适当的 Question 对象。因此,每当有人向 QuestionType 添加枚举值时,他们也必须更新该方法。但并不能解决您必须更新该方法的问题......
I'm pretty sure you just want to create a method on your enum type which will return the appropriate Question object. So anytime someone adds an enum value to QuestionType they will also have to update the method. Doesn't solve your problem of having to update that method though...