代码之家  ›  专栏  ›  技术社区  ›  meleyal

控制结构逻辑的正确顺序(真/假、假/真)?

  •  1
  • meleyal  · 技术社区  · 16 年前

    我刚开始编程,想知道是否有一种正确的方法来订购您的控制结构逻辑。

    首先检查最可能出现的情况似乎更自然,但我感觉有些控制结构将无法工作,除非它们检查所有错误以得到正确的结果(逻辑推断?)

    很难适应这种“消极”的观点,我更喜欢更积极的观点,假设一切都是真的。

    10 回复  |  直到 16 年前
        1
  •  2
  •   mfx    16 年前

    在大多数情况下,可读性比执行速度更重要。所以我尝试 使用以下方法优化以便于理解:

    所有“断言”检查都是预先完成的。这就保证了所有的错误案例都是从一开始就处理的。这对于空指针检查尤其重要,例如

        if(arg == null){ 
          throw new IllegalArgumentException();  // harsh (correct)
        }
        // or 
        if(arg == null){
            arg = "";  // forgiving (lazy)
        }
    

    接下来,我尝试在每个if语句中只检查一个条件。而不是

        if(condition1 && condition2) {
            ...
        } else {
            ...
        }
    

    我一般更喜欢

        if(condition1) {
            if(condition2) {
                ...
            } else {
                ...
            }
        } else {
            ...
        }
    

    这种方法更容易设置断点,并且使逻辑更为有利。

    我避免否定;而不是

        if(! condition) {
            ...a...
        } else {
            ...b...
        }
    

    事情最好重新安排

        if(condition) {
            ...b...
        } else {
            ...a...
        }
    

    最后,返回布尔结果的所有方法都应具有一个“正”名称,该名称指示结果的含义:

        boolean checkSomething(Something x){ ... }     // bad -- whats the result?
        boolean isSomethingInvalid(Something x){ ... } // better, but ...
        boolean isSomethingValid(Something x){ ... }   // best, no "mental negation"
    
        2
  •  13
  •   Onorio Catenacci    16 年前

    在麦康奈尔大学有一个很好的关于这个问题的讨论。 Code Complete . 我强烈推荐这本书。无论如何,相关讨论在第一版第706-708页或第二版第749-750页(多谢普林特)。从那本书里:

    安排测试,以便 最快也是最可能的是 先执行。应该很容易 通过正常情况,如果 有一些效率低下的地方,他们应该 正在处理异常。

        3
  •  6
  •   Dave DuPlantis    16 年前

    除了条件语句的值之外,还有一些事情需要考虑。例如,如果代码块的大小明显不同,您可能希望首先放置小块,以便更容易看到。(如果较大的块确实很大,则可能需要对其进行重构,或者将其提取到单独的方法中。)

    if( condition is true ) {
        do something small;
    } else { 
        do something;
        and something else; 
        . . .
        and the 20th something;
    }
    

    在条件中,是的,有一些语言在表达式的一部分为假时将停止计算表达式。如果代码中包含某种IS定义的逻辑,则需要记住这一点:如果语言计算整个表达式,则应执行以下操作:

    if( variable is defined ) {
        if( variable == value ) {
            ...
        }
    }
    

    而不是这样:

    if( (variable is defined) && (variable == value) ) {
         ...
    }
    

    我认为没有一种“正确”的方法来设计你的条件。如果你在一家有编码标准的公司工作,你应该检查一下它是否包含在标准中。(我上一次工作的地方定义了合理数量的标准,但没有指定如何编写条件逻辑。)

        4
  •  3
  •   biozinc    16 年前

    一般来说,我会先检查意外的项目,这迫使我处理程序的异常流。

    这样,我可以在开始“设置”正常程序流之前抛出异常/中止操作。

        5
  •  3
  •   Community CDub    8 年前
        6
  •  2
  •   Tom Carter    16 年前

    我的目标是构造我的条件,以尽量减少读者必须接受的信息量。有时检验阴性更容易证明阳性:

    一个例子-测试两个日期的时间段是否与另一个两个日期的时间段相交,更容易写为测试两个时间段是否相交。

        7
  •  1
  •   Sol    16 年前

    如果这是一个简单的“是”或“错误”问题,那么我通常构造一些东西,以便错误处理分支是else子句。如果这是一个“是”或“否”的问题(也就是说,这两个分支都不是一个错误),那么这纯粹是对什么感觉更自然的判断。如果在代码的核心执行之前必须进行很多测试,我通常会尝试构造一些东西,以便负测试首先出现,并以某种方式跳过后面的代码(从函数返回、中断或从循环继续)。

        8
  •  0
  •   ZCHudson    16 年前

    或/或。不过,我通常使用“消极”的方法。

    如果(!)某物) {

    }

        9
  •  0
  •   tvanfosson    16 年前

    这有点超出了问题的范围,但一般来说,您也希望您的方法很快失败。出于这个原因,我倾向于在方法的顶部进行所有参数验证,即使直到稍后在代码中才使用参数。这会损害可读性,但仅在方法非常长的情况下(必须滚动屏幕才能看到)。当然,这本身就是一种代码味道,往往会被重构出来。

    另一方面,如果检查不简单,我将把它传递给另一个方法,该方法无论如何都要检查它,我不会重复代码来签入当前方法。就像大多数事情一样,都有一个平衡。

        10
  •  0
  •   tomasv    16 年前

    (上下文:Java)

    可读性1:先解析为较小代码块的条件

    if (condition) {
      smallBlock();
    } else {
      bigBlockStart();
      ........
      bigBlockEnd();
    }
    

    可读性2:肯定断言优先,因为不注意否定符号更容易。

    有意义:使用assert.blablabla()为一个方法断言所有的前提条件,并且只对该方法所做的操作使用条件。

    推荐文章