我读过(例如来自Martin Fowler)我们应该在OOP中的(短)方法中使用保护子句而不是单一返回。我也读过(从某个地方我不记得),在可能的情况下应该避免使用else子句。
但我的同事(我在一个只有3个人的小团队中工作)迫使我不要在方法中使用多个返回,并尽可能使用else子句,即使else中只有一个注释行块。
这使我很难遵循他们的编码风格,因为例如,我无法在一个屏幕中查看方法的所有代码。当我编写代码时,我必须首先编写保护子句,然后尝试将其转换为多个返回的形式。
我错了,或者我应该怎么做?
答案 0 :(得分:32)
这是一个有争议且纯粹的审美问题。
在C和类似语言中,历史上一直避免早期返回,因为有可能错过资源清理,通常在早期返回的情况下放置在函数的末尾。
鉴于Java有例外并尝试,最后,抓住,没有必要担心早期的回报。
Personaly,我同意你的看法,因为我经常提前返回 - 这通常意味着代码更少,代码流更简单,if / else嵌套更少。
答案 1 :(得分:9)
Guard子句是一个好主意,因为它清楚地表明当前方法对某些情况不感兴趣。当你在方法的最开始时清理它并没有处理某些情况(例如当某个值小于零时),那么方法的其余部分就是它的责任的纯粹实现。
有一个更强的保护条款案例 - 在某些论证不可接受时验证输入和抛出异常的语句,例如:空值。在这种情况下,您不想继续执行,但希望在方法的最开始处抛出。这就是保护条款是最佳解决方案的地方,因为您不希望将异常抛出逻辑与您正在实施的方法的核心混合。
在讨论抛出异常的保护条款时,这里有一篇关于如何使用扩展方法在C#中简化它们的文章:How to Reduce Cyclomatic Complexity: Guard Clause。虽然该方法在Java中不可用,但它在C#中很有用。
答案 2 :(得分:5)
请他们阅读http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt,看看它是否会改变主意。 (他们的想法有历史,但我和你一起。)
编辑:以下是本文的重点。原则上采用了控制结构单一出口的原则,而不是观测数据。但是观察数据表明,允许多种方式退出控制结构会使某些问题更容易准确地解决,并且不会损害可读性。不允许它使代码更难,更容易出错。这适用于从学生到教科书作者的各种程序员。因此,我们应该允许并在适当的时候使用多个出口。
答案 3 :(得分:2)
我正处于多次返回/返回早期营地,我会游说说服其他工程师。你可以有很好的论据,并引用很多来源,但最终,你所能做的就是做出你的推销,建议妥协,做出决定,然后以团队的方式工作,这一直是它的结果。 (虽然不时重新讨论这个话题也不是不可能的。)
这实际上归结为风格,并且在宏观方案中,相对较小。总的来说,如果你能适应任何一种风格,你就是一个更有效的开发者。如果这真的“让它变得难以......遵循他们的编码风格”,那么我建议你继续努力,因为最终你会成为更好的工程师。
我曾经有一位工程师来找我并坚持要求他按照自己的编码风格进行分配(而且我们有一套非常小的指导方针)。他说,既定的编码风格伤害了他的眼睛,使他难以集中注意力(我认为他甚至可能说“恶心”。)我告诉他,如果他打算处理很多人的代码,而不仅仅是代码他写道,反之亦然。如果他无法适应约定的风格,我就无法使用他,也许这种类型的合作项目对他来说不是一个合适的地方。巧合的是,此后它不再是一个问题(虽然每次代码审查仍然是一场战斗)。