【发布时间】:2011-01-14 21:42:25
【问题描述】:
鉴于多个返回语句是可以接受的(我有点不同意,但let us digress),我正在寻找一种更可接受的方式来实现以下行为:
选项A:多次返回,重复代码块
public bool myMethod() {
/* ... code ... */
if(thisCondition) {
/* ... code that must run at end of method ... */
return false;
}
/* ... more code ... */
if(thatCondition) {
/* ... the SAME code that must run at end of method ... */
return false;
}
/* ... even more code ... */
/* ... the SAME CODE AGAIN that must run at end of method ... */
return lastCondition;
}
每次方法返回时看到相同的(小)代码块重复 3 次让我感觉很脏。此外,我想澄清一下,上面的两个return false 语句当然可以描述为返回中间方法......它们绝对不是“守卫语句”。
选项 B 稍微更容易接受吗?我觉得我可能会滥用 try/finally,我希望我应该做一些完全不同的事情。
选项 B:多次返回,try/finally 块(没有 catch 块/异常)
public bool myMethod() {
try {
/* ... code ... */
if(thisCondition) {
return false;
}
/* ... more code ... */
if(thatCondition) {
return false;
}
/* ... even more code ... */
return lastCondition;
} finally {
/* ... code that must run at end of method ... */
}
}
最后,选项 C 是我的书中最好的解决方案,但我的团队出于某种原因不喜欢这种方法,因此我正在寻找折衷方案。
选项 C:单次返回,条件块
public bool myMethod() {
/* ... code ... */
if(!thisCondition) {
/* ... more code ... */
}
if(!thisCondition && !thatCondition) {
/* ... even more code ... */
}
/* ... code that must run at end of method ... */
return summaryCondition;
}
如果您想讨论多个退货声明,请在this question 中进行。
【问题讨论】:
-
如果您还没有提供,我会选择 C 选项!你的队友对选项 C 有什么反对意见?如果“必须在方法结束时运行的代码”需要更改会发生什么?
-
我同意多纳尔的观点。我喜欢选项 C。他们的具体反对意见是什么?
-
我真的不想为他们说话,但据我了解,他们不喜欢选项 C 仅仅是因为它没有多个返回语句。我不确定这是一个站得住脚的立场,但这是另一个话题。
-
如果它类似于
if(!save(foo)) return false;,我建议从save(..)抛出一个异常,以迫使人们处理这种情况而不是忽略它(或忘记它!)。如果它更接近if (count() == 0) return false;,那么一个例外显然没有意义,C 将是我的选择(使用@Loadmaster 的简化)。 -
值得指出的是,选项 B 中使用的 try-finally 等效于在其他语言中经常受到称赞的范围绑定资源管理(SBRM,有时称为 RAII)。
标签: java language-agnostic coding-style