我遇到了设计问题:
但我对NumberQuestion有疑问。我必须采取正确的答案,将其转换为数字,并与用户的答案进行比较。那么我该如何得到答案呢?使用getter方法并不安全。或者我的设计不好?我怎样才能改变?
public abstract class Question { private String question; private String answer; public Question(String question, String answer) { this.question = question; this.answer = answer; } public boolean checkAnswer(String yourAnswer) { // default implementation } } class TextQuestion extends Question { // Answer and Question is always string type, it's OK, not problem } class NumberQuestion extends Question { // Question is String, OK // Answer: input is number, accept approximately // Ex: Question: 1/3 = ? // Answer: 0.3 or 0.33 or 0.333 are accepted (using an Epsilon value) // so must override checkAnswer public boolean checkAnswer(String yourAnswer) { // HOW can I do? } }
答案 0 :(得分:4)
我不明白为什么你需要从子类(或任何客户端代码)隐藏答案。客户端代码肯定需要首先知道答案才能创建TextQuestion
或NumberQuestion
实例。
您应该从Question
类中抽象出测试的逻辑以及答案类型:
public abstract class Question<AnswerType> {
private String question;
private AnswerType answer;
public Question(String question, AnswerType answer) {
this.question = question;
this.answer = answer;
}
public abstract boolean checkAnswer(AnswerType yourAnswer);
protected AnswerType getAnswer() {
return answer;
}
}
class TextQuestion extends Question<String> {
public TextQuestion(String question, String answer) {
super(question, answer);
}
public boolean checkAnswer(String yourAnswer) {
return answer.equals(yourAnswer);
}
}
class NumberQuestion extends Question<Double> {
private double epsilon;
public NumberQuestion(String question, Double answer, double epsilon) {
super(question, answer);
this.epsilon = epsilon;
}
public boolean checkAnswer(Double yourAnswer) {
return Math.abs(getAnswer() - yourAnswer) < epsilon;
}
}
答案 1 :(得分:1)
如果您的答案可以有不同的类型,您也可以在抽象类中使用泛型。
public abstract class Question<T> {
private final String question;
protected final T answer;
public Question(String question, T answer) {
this.question = question;
this.answer = answer;
}
//Default implementation
public boolean checkAnswer(T yourAnswer) {
return answer.equals(yourAnswer);
}
}
当您定义子类时:
class NumberQuestion extends Question<BigDecimal> {
...
private final BigDecimal epsilon;
public NumericQuestion(String question, BigDecimal answer, BigDecimal epsilon) {
super(question, answer);
this.epsilon = epsilon;
}
@Override
public boolean checkAnswer(BigDecimal yourAnswer) {
BigDecimal result = this.answer.subtract(yourAnswer).abs();
return (result.compareTo(epsilon) == -1); // check whether result < epsilon
}
}
顺便说一下,使用BigDecimal进行浮点计算,而不是更好。有很多关于此的好文章。如果您对此感兴趣,可以“谷歌”这个问题。
如果需要设置浮点数的比例,可以使用大小数字轻松完成此操作,例如:
result = result.setScale(5);
请注意,因为BigDecimal类是不可变的(不完全,但这是另一个问题)并在您尝试更改其状态时返回新实例。
答案 2 :(得分:0)
我不确定你是否熟悉泛型类,但在这种情况下这是合适的。你可以谷歌吧。 : - )
如果您不想这样做,您可以随时将yourAnswer
和this.answer
转换为相同的类型,然后您可以找到绝对差异,并确保它们低于特定的阈。