简体   繁体   English

我应该使用 guard 子句,并尽量避免 else 子句吗?

[英]Shall I use guard clause, and try to avoid else clause?

I've read (eg from Martin Fowler) that we should use guard clause instead of single return in a (short) method in OOP. I've also read (from somewhere I don't remember) that else clause should be avoided when possible.我读过(例如从 Martin Fowler 那里)我们应该在 OOP 的(短)方法中使用保护子句而不是单一返回。我也读过(从我不记得的地方)应该避免使用 else 子句可能的。

But my colleagues (I work in a small team with only 3 guys) force me not to use multiple returns in a method, and to use else clause as much as possible, even if there is only one comment line in the else block.但是我的同事(我在一个只有 3 个人的小团队工作)强迫我不要在一个方法中使用多个 return,并且尽可能使用 else 子句,即使 else 块中只有一个注释行。

This makes it difficult for me to follow their coding style, because for example, I cannot view all code of a method in one screen.这让我很难遵循他们的编码风格,因为例如,我无法在一个屏幕上查看一个方法的所有代码。 And when I code, I have to write guard clause first, and then try to convert it into the form with out multiple returns.而我写代码的时候,必须先写guard clause,然后再尝试转换成没有multiple return的形式。

Am I wrong or what should I do with it?我错了还是我应该怎么办?

This is arguable and pure aesthetic question. 这是有争议的纯粹的审美问题。

Early return has been historically avoided in C and similar languages since it was possible to miss resource cleanup which is usually placed at the end of the function in case of early return. 在C和类似语言中,历史上避免了早期返回,因为有可能错过资源清理,这通常在早期返回的情况下放置在函数的末尾。

Given that Java have exceptions and try, catch, finally, there's no need to fear early returns. 鉴于Java有例外并试图抓住,最后,没有必要担心早期的回报。

Personaly, I agree with you, since I do early return often - that usually means less code and simpler code flow with less if/else nesting. Personaly,我同意你的看法,因为我经常提前返回 - 这通常意味着代码更少,代码流更简单,if / else嵌套更少。

Guard clause is a good idea because it clearly indicates that current method is not interested in certain cases. Guard子句是一个好主意,因为它清楚地表明当前方法对某些情况不感兴趣。 When you clear up at the very beginning of the method that it doesn't deal with some cases (eg when some value is less than zero), then the rest of the method is pure implementation of its responsibility. 当你在方法的最开始清理它没有处理某些情况时(例如当某个值小于零时),那么方法的其余部分就是它的责任的纯粹实现。

There is one stronger case of guard clauses - statements that validate input and throw exceptions when some argument is unacceptable, eg null. 有一个更强的保护条款案例 - 在某些参数不可接受时验证输入和抛出异常的语句,例如null。 In that case you don't want to proceed with execution but wish to throw at the very beginning of the method. 在这种情况下,您不希望继续执行,但希望在方法的最开始处抛出。 That is where guard clauses are the best solution because you don't want to mix exception throwing logic with the core of the method you're implementing. 这就是保护条款是最佳解决方案的地方,因为您不希望将异常抛出逻辑与您正在实现的方法的核心混合在一起。

When talking about guard clauses that throw exceptions, here is one article about how you can simplify them in C# using extension methods: How to Reduce Cyclomatic Complexity: Guard Clause . 在讨论抛出异常的guard子句时,这里有一篇关于如何使用扩展方法在C#中简化它们的文章: 如何减少Cyclomatic Complexity:Guard Clause Though that method is not available in Java, it is useful in C#. 尽管该方法在Java中不可用,但它在C#中很有用。

Have them read http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt and see if it will change their minds. 让他们阅读http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt ,看看它是否会改变他们的想法。 (There is history to their idea, but I side with you.) (他们的想法有历史,但我和你在一起。)

Edit: Here are the critical points from the article. 编辑:这是文章中的关键点。 The principle of single exits from control structures was adopted on principle, not observational data. 原则上采用了控制结构单一出口的原则,而不是观测数据。 But observational data says that allowing multiple ways of exiting control structures makes certain problems easier to solve accurately, and does not hurt readability. 但是观察数据表明,允许多种方式退出控制结构会使某些问题更容易准确地解决,并且不会损害可读性。 Disallowing it makes code harder and more likely to be buggy. 不允许它使代码更难,更容易出错。 This holds across a wide variety of programmers, from students to textbook writers. 这适用于从学生到教科书作者的各种程序员。 Therefore we should allow and use multiple exits where appropriate. 因此,我们应该允许并在适当的时候使用多个出口。

I'm in the multiple-return/return-early camp and I would lobby to convince other engineers of this. 我正处于多次返回/返回早期营地,我会游说说服其他工程师。 You can have great arguments and cite great sources, but in the end, all you can do is make your pitch, suggest compromises, come to a decision, and then work as a team, which ever way it works out. 你可以有很好的论据,并引用很多来源,但最终,你所能做的就是做出你的推销,建议妥协,做出决定,然后以团队的方式工作,这一直是它的结果。 (Although revisiting of the topic from time to time isn't out of the question either.) (虽然不时重新讨论这个话题也不是不可能的。)

This really just comes down to style and, in the grand scheme of things, a relatively minor one. 这真的只取决于风格,在宏观方案中,相对较小。 Overall, you're a more effective developer if you can adapt to either style. 总的来说,如果你能适应任何一种风格,你就是一个更有效的开发者。 If this really "makes it difficult ... to follow their coding style", then I suggest you work on it, because in the end, you'll end up the better engineer. 如果这真的“让它变得难以......遵循他们的编码风格”,那么我建议你继续努力,因为最终,你将成为更好的工程师。

I had an engineer once come to me and insist he be given dispensation to follow his own coding style (and we had a pretty minimal set of guidelines). 我曾经有一位工程师来找我并坚持要他按照自己的编码风格给予特许(我们有一套非常小的指导方针)。 He said the established coding style hurt his eyes and made it difficult for him to concentrate (I think he may have even said "nauseous".) I told him that if he was going to work on a lot of people's code, not just code he wrote, and vice versa. 他说,既定的编码风格伤害了他的眼睛,使他难以集中注意力(我认为他甚至可能说“恶心”。)我告诉他,如果他打算处理很多人的代码,而不仅仅是代码他写道,反之亦然。 If he couldn't adapt to work with the agreed upon style, I couldn't use him and that maybe this type of collaborative project wasn't the right place for him. 如果他无法适应约定的风格,我就无法使用他,也许这种类型的合作项目对他来说不是一个合适的地方。 Coincidentally, it was less of an issue after that (although every code review was still a battle). 巧合的是,在此之后它不是一个问题(虽然每个代码审查仍然是一场战斗)。

My issue with guard clauses is that 1) they can be easily dispersed through code and be easy to miss (this has happened to me on multiple occasions) and 2) I have to remember which code has been "ejected" as I trace code blocks which can become complex and 3) by setting code within if/else you have a contained set of code that you know executes for a given set of criteria.我对保护条款的问题是 1) 它们可以很容易地分散在代码中并且很容易被遗漏(这在我身上发生过多次)和 2) 我必须记住在跟踪代码块时哪些代码被“弹出”这可能会变得复杂,并且 3) 通过在 if/else 中设置代码,您拥有一组您知道针对给定条件执行的代码。 With guard conditions, the criteria is EVERYTHING minus what the guard has ejected.对于守卫条件,标准是一切减去守卫弹出的内容。 It is much more difficult for me to get my head around that.对我来说,解决这个问题要困难得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM