【问题标题】:Where is the right balance of predicates in a single if statement?单个 if 语句中谓词的正确平衡在哪里?
【发布时间】:2009-04-14 10:02:30
【问题描述】:

我个人对下面的代码没有问题

if (Object foo != null && !String.IsNullOrEmpty(foo["bar"]))
{
    // do something
}

因为我觉得下面的内容太冗长了

if (Object foo != null)
{
    if (!String.IsNullOrEmpty(foo["bar"]))
    {
        // do something
    }
}

但是如果说有 5 个谓词并且我必须将文本包装在编辑器中以一次查看它们,那么我不会在这个观点上走得太远,是否有一条逻辑“线”来说明如何绘制您在单个 if 语句中包含许多谓词,类似于说方法永远不需要超过 7 个参数

【问题讨论】:

  • 永远不要说永远。你曾经在 printf 函数家族中使用过 7 个以上的参数吗?

标签: language-agnostic coding-style


【解决方案1】:

我不认为将 if 语句重写为两个是一种方式,尤其是如果您认为在示例中添加 else 子句会产生不同的结果。如果我想减少条件中的原子命题的数量,我会将一些有意义的因素一起考虑到它们自己的函数中,例如:

if(won_jackpot(obj)) ...

【讨论】:

    【解决方案2】:

    我认为这是不同类型的运算符和正确格式之间的平衡。如果所有运算符都相同(全是“与”或全是“或”),那么您可能可以将不定数量的表达式连接在一起而不会失去理解:

    if (something() &&
        something_else() &&
        so_on() &&
        so_forth() &&
        some_more_stuff() &&
        yada() &&
        yada() &&
        yada() &&
        newman() &&
        soup_nazi() &&
        etc())
      ...
    

    【讨论】:

      【解决方案3】:

      短期记忆有七个项目的容量,给予或接受两个。这意味着涉及超过五个不同对象的表达式可能需要一个人停下来思考。

      【讨论】:

        【解决方案4】:

        我不相信有一个神奇的数字。如果所有谓词一起有意义,那么我会将它们放在一起。这可能涉及将 if 语句分成两行,但我通常从不引入多余的 if 语句。但如果特别长,你应该问问自己,所有的陈述是否真的有必要。也许您可以更早地过滤掉一些值或类似的东西。最大的担忧是可读性。如果其他人难以理解,则需要重构代码。但是将代码分成两个不同的 if 语句很少会使代码更具可读性,它只会占用更多的行数。

        【讨论】:

          【解决方案5】:

          不是谓词的数量,而是复杂性。只要你能以最小的努力理解代码的作用,我觉得没问题。

          此外,我不会更改为多个 if,但我会为谓词添加一个函数。特别是在多个地方使用相同数量的谓词时。

          【讨论】:

            【解决方案6】:

            这取决于你在做什么。当您反转第二条语句时,它会产生不同的结果。 (在它前面添加一个“not”)并且是一个非常常见的错误来源。

            我已经看到了包含大约 20 个谓词的代码(或者至少,工作得很好!) 我使用的经验法则,如果它看起来像狗晚餐,我会考虑重构。

            【讨论】:

              【解决方案7】:

              我不认为有任何规则,但是:

              1. 它是否足够复杂,以至于当您向其他人展示时,他们很难理解?
              2. 是否需要覆盖多行?
              3. 您是否在多个“if”子句中重复进行条件检查?这表明需要对某些方法进行重构

              如果上述任何一个适用,我会重新设计。

              【讨论】:

                【解决方案8】:

                条件列表长的问题与其说是可读性的损失,不如说是可测试性的损失。尤其是在处理错误的方法参数时,有时请求宽恕而不是许可确实更容易(例如,请参阅this question 的答案)。这样您就可以保持代码干净和可测试,并修复调用者或让他们处理产生的异常。

                【讨论】:

                  【解决方案9】:

                  这完全取决于需要做什么。但是你可能想要研究的一件事会使某些算法不那么冗长,那就是 switch 语句:

                  switch (myVal)
                  {
                      case "isThis":
                      case "isThat":
                      case "something else":
                          doThis();
                          break;
                      case "another":
                      case "yet another":
                      case "even another":
                          doThat();
                          break;
                      case "another one":
                      case "more more":
                          doThisAgain();
                          break;
                  }

                  在 if else 语句中这样做会非常冗长。有些代码需要大量的 if 和 else 语句,有些可以被压缩,等等。永远不要为了代码源的美观而牺牲代码执行的质量。

                  【讨论】:

                    【解决方案10】:

                    哪种方式更好?两者都不。两者的语义不同。

                    我同意虽然拆分使调试更容易,但条件断点也是如此:)

                    如果是 'AND's 或 'OR's 的简单组合超过 3 个测试,则重构它。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2017-03-26
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-01-21
                      • 1970-01-01
                      • 2016-06-10
                      • 1970-01-01
                      相关资源
                      最近更新 更多