,假设您有一种检查参数(答案)是否正确的方法,并检查列表中是否已经有正确的答案:
public void addAnswer(Answer answer) {
if (answer.isCorrect()) {
...
}
}
但是,我只希望一个答案在列表中正确。我有多个选择。我可以抛出一个例外,我可以忽略它,我可以从Addanswer返回一些布尔值,告诉我操作是否还可以。您应该如何在这样的情况下思考?
规则很简单:在例外,错误,未预测的失败。当您期望发生某些事情或经常发生某些事情时,请不要使用异常。
在您的情况下,答案是不正确的不是错误或真正罕见的东西。这是您业务逻辑的一部分。您 can 都会引发异常,但仅作为某些验证的一部分(断言),如果您期望在给定点的答案始终是正确的,突然间这不是(前提条件失败)。
当然,如果需要检查正确性时发生某些故障(数据库连接丢失,错误阵列索引)。像一吨砖头那样向下,我为此答案,并带有诸如"不使用流量控制的例外"one_answers"不要在正常情况下使用异常"之类的陈述。
第一个语句的麻烦是例外是流控制的一种形式。这使得论点是自相矛盾的,因此无效。
第二个陈述的麻烦在于,它似乎不可避免地会随着正常的无限重新定义出色的条件。您将在此网站中找到示例:例如,警方坚持认为EOF是"正常"的热烈讨论,因此,尽管存在数十个Java API,但不应抓住Eofexception。选择这件事。沿着这条路走足够远,您最终没有任何异常的东西,因此根本没有机会使用它们。
这些不是逻辑参数。这些是未经检查的教条。
原来的和真实的观点,早在1989年首次制定时,您不应该给自己提供例外,以相同的方法处理:,换句话说,不要将其视为goto。这个原理继续具有有效性。
关于检查的例外的要点是,您 force 呼叫者在处理它们方面做点什么。如果您相信自己想要的是您想要的,请使用异常。或者,如果您使用的是迫使您抓住它们的API,请在适当的层面上捕获它们(无论是:留作读者的练习)。
换句话说,就像现实世界中的大多数事情一样,这取决于您的酌处权和判断力。该功能可以在那里使用或滥用,就像其他任何事物一样。
@Exception警察:您会在电话簿中找到我。但是要为参数做好准备。
这完全取决于您想要实现的>。您方法的呼叫者是否应该已经确保不会添加两个正确的答案?如果发生这种情况,它是编程错误的迹象吗?然后提出异常,但绝对未选中的异常。
如果您的方法的目的是减轻呼叫者的执行单一撤离不变式(我怀疑),那么您可以通过boolean
返回值安排发出信号,这仅使其成为一个可选的信息频道对于呼叫者。
如果有没有办法提前知道是否还有其他正确的答案—例如,从多个线程甚至过程(通过数据库)同时添加答案扔检查了异常。
有意义底线:没有一种尺寸的最佳实践,但是对于您想完成的每种情况都有最佳实践。
从方法中提出的一个例外可以强制呼叫者在预期某些输入发生的例外情况下采取一些措施。返回值并非强制执行,因此由呼叫者捕获并采取一些措施。
如果您希望呼叫者处理场景以采取一些纠正措施,则应提出一个检查的例外(java.lang.Exception
的子类)。
这里的问题是您的API易于使用。我会使用以下方案:
public class Question {
private List<Answer> answers;
private int mCorrect;
// you may want a List implementation without duplicates
public void setAnswers(List<Answer> answers, int correct) {
this.answers = answers;
// check if int is between bounds
mCorrect = correct;
}
public boolean isCorrect(Answer answer) {
return answers.indexOf(answer) == mCorrect;
}
}
因为Answer
本身就是一个语句,并且通常不能在不与Question
关联的情况下为false
的true
。此API使得不可能具有零或多个正确的答案,并迫使用户在添加答案时提供正确的答案,因此您的程序始终处于一致的状态,根本不会失败。
在确定如何发出信号之前,设计API总是更好,以使错误不那么常见。通过当前的实施,您必须在自己的身边进行检查,客户程序员也必须在他的身边进行检查。使用建议的设计不需要检查,您将在两侧都有正确,简洁和流利的代码。
关于何时使用boolean
以及何时使用Exception
s,我经常看到布尔来镜像基础API(主要是低级C代码)。
我同意Tomasz Nurkiewicz的回应。我无法对此发表评论,因为我是新用户。我还建议,如果Addanswer()方法并不总是会添加答案(因为它们已经存在正确的答案),请命名以建议这种行为。"添加"是建议正常的收集行为。
public boolean submitAnswer(Answer answer); // returns true is answer accepted
您的确切解决方案可能取决于我们不知道的有关您的应用程序的大图。也许您确实想提出例外,但也使呼叫者的责任检查添加答案是否有效。
这都是一个丰富的挂毯。
我将以这种方式实现它:
public class Question {
private int questionId;
private final Set<Answer> options = new HashSet<Answer>();
private final Set<Answer> correctAnswers = new HashSet<Answer>();
public boolean addAnswer(Answer answer) throws WrongAnswerForThisQuestionException {
if(!answer.isValid(questionId)) {
throw new WrongAnswerForThisQuestionException(answer, this);
}
if (answer.isCorrect(questionId)) {
correctAnswers.add(answer);
}
return options.add(answer);
}
}