本文介绍了在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中增加工厂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 06:22