在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."); } } 

这个现在可行了。 如果我想添加另一个问题类型,我将需要修改工厂类,我不想这样做。

如何设置它以便每个问题类在Factory中注册自己,这样当我添加新的问题类型时,我不必更改工厂的代码? 我对java有点新,我不知道该怎么做。

编辑

附加信息

所有问题类都实现了IQuestion接口。 我正在寻找一种方法来实现像这样的方法

 public static void registerType(QuestionType quesType, Class ques) 

这样我就可以从我的类中的静态块调用这个方法,这样当我添加一个新的问题类型时,我就不必在Question Factory中更改或添加任何代码了。 我知道我必须更改当前的实现以使其通用。 我不确定我上面写的方法在语法上是否正确,但它在概念中显示了我想要的东西。

您可以使用您已经显示的注册方法,通过Reflection API( Class thingy)来实现。

我不熟悉Java Reflection来写一个更有帮助的答案,但是如果你寻找一些getConstructor方法或其他东西你可能会到达那里。

要调用该方法,您应该执行类似的操作(请注意.class语法):

 QuestionFactory.registerType(QuestionType.TrueFalse, TrueFalseQuestion.class); 

编辑啊,不管怎样,我有时间去调查。 尝试这个:

 public class QuestionFactory { static final Map> map = new HashMap>(); public static void registerType(QuestionType quesType, Class ques) { map.put(quesType, ques.getConstructor()); } public static Question createQuestion(QuestionType quesType) { return map.get(quesType).newInstance(); } } 

我没有编译这个,但它应该工作,或者至少指导你正确的方向。 为此,Question实现必须具有不带参数的构造函数。

因为您正在使用静态工厂(也称为面向对象的全局变量),所以您可以使问题在静态初始化程序中注册。

 public class TrueFalseQuestion implements Question { static { QuestionFactory.registerType(QuestionType.TrueFalse, TrueFalseQuestion.class); } // Whatever else goes here } 

一种可能性:

 public enum QuestionType { TrueFalse(TrueFalseQuestion.class), MultipleChoice(MultipleChoiceQuestion.class), Essay(EssayQuestion.class) private final Class implementationType; QuestionType(Class implementationType) { this.implementationType = implementationType; } public Question createQuestion() { return implementationType.newInstance(); } } 

当然,这摆脱了工厂,并假设你的所有问题都没有args构造函数,但据我所知,它涵盖了上面代码草图的所有情况。 如果特殊类的构造更复杂,您可以始终设置如下:

 public enum QuestionType { TrueFalse { public Question createQuestion() { /* construction logic goes here */ } } public abstract Question createQuestion(); } 

我很确定你只想在你的枚举类型上创建一个方法,它将返回相应的Question对象。 因此,只要有人向QuestionType添加枚举值,他们就必须更新方法。 虽然不能解决你必须更新该方法的问题…