我知道这是一个风格问题,因此是主观标签。我有一小段代码,有两个嵌套条件。我可以用两种方式对它进行编码,我希望看到更有经验的开发人员认为应该是这样的。
样式1 :
while (!String.IsNullOrEmpty(msg = reader.readMsg()))
{
RaiseMessageReceived();
if (parseMsg)
{
ParsedMsg parsedMsg = parser.parseMsg(msg);
RaiseMessageParsed();
if (processMsg)
{
process(parsedMsg);
RaiseMessageProcessed();
}
}
}
样式2:
while (!String.IsNullOrEmpty(msg = reader.readMsg()))
{
RaiseMessageReceived();
if (!parseMsg) continue;
ParsedMsg parsedMsg = parser.parseMsg(msg);
RaiseMessageParsed();
if (!processMsg) continue;
process(parsedMsg);
RaiseMessageProcessed();
}
(旁边的问题:如何在源代码示例中添加空行?)
答案 0 :(得分:22)
我更喜欢Style 1 - 带缩进。
答案 1 :(得分:13)
我更喜欢Style 2 - 使用continue语句。
答案 2 :(得分:8)
原则上我同意大多数喜欢风格1的人。这就是Steve Mcconnell在“代码完成”中所赞同的 - 说出你的意思,即你是否对条件是真实的更感兴趣,而虚假状态是罕见的或不首选,然后说明首选版本。
在实践中虽然我经常发现自己使用样式2,因为我喜欢先清除所有可能的错误/无效状态。在我摆脱了我不感兴趣的所有可能性之后,我可以将心脏代码编写到例程的末尾,而不必经常想知道我是否需要防范某些条件或其他条件。基本上,态度是,摆脱糠,,然后平静地做真正的工作。
答案 3 :(得分:5)
这两个都是虚假的。不要将赋值放在条件表达式中。
(!String.IsNullOrEmpty(msg = reader.readMsg()))
你只是这样做是因为读者的行为不稳定 - 为什么读者会给你一条非信息表明读完了?这是一个有更好设计的读者的替代方案:
while (reader.HasMessage())
{
string msg = reader.GetMessage();
HandleMessage(msg);
}
答案 4 :(得分:4)
我绝对更喜欢第一个版本。当过度使用时,continue
语句非常好。
我将这与多个return语句一样对待。它们适用于防护条款,并且在提高清晰度时具有良好的实用性,但不应过度使用。
此外,一行中的两个空格应该在代码块中为您插入换行符。
答案 5 :(得分:3)
我更喜欢Style2。此外,在Refactoring.com上描述了相同的样本 Replace Nested Conditions
答案 6 :(得分:3)
我想以不同的方向重构此代码。你的代码做了太多事情!
我认为我们需要在这里进行一些分离。我想探索:
yield return
)。答案 7 :(得分:2)
在所示的示例中,我将使用样式1.如果我的方法足够大以至于嵌套成为问题(并且没有更好的方法来重构代码),那么我会考虑样式2但是对于所显示的两个小巧的案例,肯定是风格1。
答案 8 :(得分:2)
风格1简直就是CLEARER,恕我直言。没有什么可以反对继续本身,但正如人们之前所说的,缩进使得更容易追随。
答案 9 :(得分:2)
样式2让人类读者专注于重要的代码,甚至不看任何不相关的东西 - 你会看到continue语句,下面的任何内容都无关紧要。
样式2管理复杂性,因此可以扩展到更复杂的方法,样式1很快变得难以管理。答案 10 :(得分:2)
出于多种原因,我个人更喜欢风格2;
你可以点击一个潜在的错误,你在if之后缩进但忘记了大括号。
您遇到浮动的其他问题的风险较小,例如,如果有其他属于的话,您可能会混淆多个嵌套ifs。
您可以避免过多的缩进,从而导致代码离开页面
当我编码时,我倾向于将继续分开;
if (!parseMsg)
continue;
由于它使其更加明显的原因,并且更容易为其分配断点。
答案 11 :(得分:1)
我发现继续语句使代码更难以遵循(因此调试)。有些情况下你可能会使用它们,但我认为你的例子不是其中之一。
答案 12 :(得分:1)
虽然我更喜欢样式1.我发现有时使用样式2很有用,因为它有助于降低缩进级别并使代码更容易阅读。
任何一种风格都是诚实的,这完全取决于个人选择。
答案 13 :(得分:0)
两种选择都很尴尬。从样式2 开始,将while循环的内部提取到新方法中,并将continue语句更改为return语句。它仍然需要更多的重构。
continue关键字很笨拙,但很容易理解return语句。此选项几乎没有嵌套缩进。
答案 14 :(得分:0)
尽可能避免使用continue
语句。
我们尽量避免使用goto
,不要我们 - 它是否也有意义避免它的堂兄continue
?
答案 15 :(得分:0)
我发现风格1更容易理解。所以我更喜欢风格1。
答案 16 :(得分:0)
Guard子句适用于条件函数返回,因为它创建了一个完整的语句。在一个地方,你知道发生了什么(我们在这里完成)。
continue语句通常需要更多考虑。我个人觉得如果你在一个循环中使用多个continue语句,那你就做错了。
我认为第一种类型是自我记录和标准方式。当你违反标准方式时,你需要添加评论。
答案 17 :(得分:0)
如果某人以后必须维护此代码以在msg上添加可能或可能不依赖于消息是否已被解析和/或处理的进一步操作,那么如果代码的格式为1,则更简单。在风格2中,因此我更喜欢风格1.
答案 18 :(得分:0)
我的偏好是样式1,但如果!parseMsg或!processMsg经常发生,我会在心跳中使用样式2。总是把最可能的情景放在第一位 - 对吧?
答案 19 :(得分:0)
在担心化妆品不相关之前,我会删除使用全局变量来在函数之间进行通信。据推测,您的语言支持函数的返回值。使用这些
哪个更清楚。
答案 20 :(得分:0)
我更喜欢样式1并将continue语句等同于goto语句。我承认它在执行过程中可能不如另一个有效,但我发现代码理解效率几乎总是比代码执行效率更重要。
答案 21 :(得分:0)
第一种风格肯定更清晰 - 它表示你(显然)意味着什么,即获取消息,如果设置了parseMsg
标志,则尝试解析它;如果成功,请处理它。另一方面,第二个版本将处理明显更少的指令,尤其是在设置parseMsg
的情况下。我很想走到两者之间:
while (!String.IsNullOrEmpty(msg = reader.readMsg())){
RaiseMessageReceived();
if (!parseMsg) continue ;
ParsedMsg parsedMsg = parser.parseMsg(msg);
RaiseMessageParsed();
if (processMsg){
process(parsedMsg);
RaiseMessageProcessed();
}
}
...关于你在解析被关闭的特殊情况下跳过所有解析的理论。
答案 22 :(得分:0)
我更喜欢带有缩进的样式1,它更清晰,更容易理解只是通过查看它我可以看到代码的布局。