我应该使用保护条款,并尽量避免使用其他条款?

cha*_*nce 18 java if-statement coding-style

我读过(例如来自Martin Fowler)我们应该在OOP中的(短)方法中使用保护子句而不是单一返回.我也读过(从我不记得的某个地方)应尽可能避免使用else子句.

但我的同事(我在一个只有3个人的小团队中工作)迫使我不要在方法中使用多个返回,并尽可能使用else子句,即使else块中只有一个注释行.

这使我很难遵循他们的编码风格,因为例如,我无法在一个屏幕中查看方法的所有代码.当我编写代码时,我必须首先编写保护子句,然后尝试将其转换为具有多个返回的形式.

我错了,或者我应该怎么做?

Mar*_*rko 33

这是有争议的纯粹的审美问题.

在C和类似语言中,历史上避免了早期返回,因为有可能错过资源清理,这通常在早期返回的情况下放置在函数的末尾.

鉴于Java有例外并试图抓住,最后,没有必要担心早期的回报.

Personaly,我同意你的看法,因为我经常提前返回 - 通常意味着代码更少,代码流更简单,if/else嵌套更少.

  • +1指出它是有争议的.为了便于阅读,我更喜欢提前退货. (11认同)
  • 如果我的记忆对我有用,那么避免早期返回(或从循环中断)的另一个原因是理论上更容易证明你的代码是正确的.(又称正式验证) (2认同)
  • 这完全是主观的,但喜欢筑巢条件的人是错误的。 (2认同)

Zor*_*vat 10

Guard子句是一个好主意,因为它清楚地表明当前方法对某些情况不感兴趣.当你在方法的最开始清理它没有处理某些情况时(例如当某个值小于零时),那么方法的其余部分就是它的责任的纯粹实现.

有一个更强的保护条款案例 - 在某些参数不可接受时验证输入和抛出异常的语句,例如null.在这种情况下,您不希望继续执行,但希望在方法的最开始处抛出.这就是保护条款是最佳解决方案的地方,因为您不希望将异常抛出逻辑与您正在实现的方法的核心混合在一起.

在讨论抛出异常的guard子句时,这里有一篇关于如何使用扩展方法在C#中简化它们的文章:如何减少Cyclomatic Complexity:Guard Clause.尽管该方法在Java中不可用,但它在C#中很有用.


bti*_*lly 5

让他们阅读http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt,看看它是否会改变他们的想法.(他们的想法有历史,但我和你在一起.)

编辑:这是文章中的关键点.原则上采用了控制结构单一出口的原则,而不是观测数据.但是观察数据表明,允许多种方式退出控制结构会使某些问题更容易准确地解决,并且不会损害可读性.不允许它使代码更难,更容易出错.这适用于从学生到教科书作者的各种程序员.因此,我们应该允许并在适当的时候使用多个出口.


Ber*_*t F 5

我属于多次返回/提前返回阵营,我会游说说服其他工程师相信这一点。你可以有很好的论据并引用很好的资料来源,但最终,你所能做的就是提出自己的主张,提出妥协,做出决定,然后作为一个团队工作,无论结果如何。(尽管时不时地重新讨论这个话题也不是不可能的。)

这实际上只是归结为风格,而且从整体来看,这是一个相对较小的问题。总的来说,如果您能够适应这两种风格,那么您就是一名更高效的开发人员。如果这确实“使得遵循他们的编码风格变得困难”,那么我建议您努力解决它,因为最终,您将成为更好的工程师。

有一次,一位工程师来找我,坚持要求他遵循自己的编码风格(而且我们有一套非常简单的指导方针)。他说既定的编码风格伤害了他的眼睛,让他很难集中注意力(我想他甚至可能会说“恶心”。)我告诉他,如果他要处理很多人的代码,而不仅仅是代码他写道,反之亦然。如果他不能适应约定的风格,我就不能使用他,也许这种类型的合作项目不适合他。巧合的是,此后问题就不那么严重了(尽管每次代码审查仍然是一场战斗)。