如果每个答案都可以编码为字符串,则可以执行以下操作:
interface Question {
int score(String answer);
void display(String answer);
void displayGraded(String answer);
}
空字符串表示问题所在,尚无答案。这样可以将问题,答案和GUI分开,但允许多态。
class MultipleChoice implements Question {
MultipleChoiceView mcv;
String question;
String answerKey;
String[] choices;
MultipleChoice(
MultipleChoiceView mcv,
String question,
String answerKey,
String... choices
) {
this.mcv = mcv;
this.question = question;
this.answerKey = answerKey;
this.choices = choices;
}
int score(String answer) {
return answer.equals(answerKey); //Or whatever scoring logic
}
void display(String answer) {
mcv.display(question, choices, answer);
}
void displayGraded(String answer) {
mcv.displayGraded(
question,
answerKey,
choices,
answer,
score(answer)
);
}
}
文本框,匹配项等可以具有类似的设计,全部实现问题界面。答案字符串的构造在视图中进行。答案字符串代表测试状态。它们应随着学生的进步而存储。将其应用于问题可以以分级和非分级方式显示测试及其状态。
通过将输出分为display()
和displayGraded()
,不需要交换视图,也不需要对参数进行任何分支。但是,每个视图在显示时可以自由地重用尽可能多的显示逻辑。无论采用哪种方案设计,都无需泄漏到此代码中。
但是,如果您希望对问题的显示方式有更多的动态控制,可以执行以下操作:
interface Question {
int score(String answer);
void display(MultipleChoiceView mcv, String answer);
}
还有这个
class MultipleChoice implements Question {
String question;
String answerKey;
String[] choices;
MultipleChoice(
String question,
String answerKey,
String... choices
) {
this.question = question;
this.answerKey = answerKey;
this.choices = choices;
}
int score(String answer) {
return answer.equals(answerKey); //Or whatever scoring logic
}
void display(MultipleChoiceView mcv, String answer) {
mcv.display(
question,
answerKey,
choices,
answer,
score(answer)
);
}
}
这确实有一个缺点,那就是需要不需要显示的视图,score()
或者answerKey
在不需要视图时不依赖它们的视图。但这意味着您不必为希望使用的每种视图重新构建测试题。