【问题标题】:Coding style - how do I format a long if condition to make it readable编码风格 - 如何格式化长 if 条件以使其可读
【发布时间】:2013-04-16 23:59:33
【问题描述】:

我有一个很长的 if 条件,如下所示。有两个条件必须不满足,才能评估语句。我确实将它作为一个带有很多 && 和的衬里!但它变得不可读。我尝试将其拆分为if elsif else,它更具可读性但读起来不太好,因为第一个if elsif 块中没有代码。

整理此代码块的最佳做法是什么?

if ($instructionObject->instruction=='nesting_grammar' && $instructionObject->match=='>'){ //if instruction is a '>' child indicator
   //don't change the child depth
}else if ($instructionObject->instruction=='selector' && is_object($this->instructions[$key+1]) && $this->instructions[$key+1]->instruction == 'nesting_grammar' && $this->instructions[$key+1]->match == '>'){ //if instruction is a selector followed by a '>'
   //don't change the child depth
}else{
   $insertOffset += $childDepth;
   unset($childDepth);
}

【问题讨论】:

    标签: php coding-style


    【解决方案1】:

    您可以使用“extract method”重构。将您的条件替换为新方法。

    if ($this->isInstructionNestingGrammar($instructionObject)){ 
       //don't change the child depth
    }else if ($this->isIntructionSelect($instructionObject)){ 
       //don't change the child depth
    }else{
       $insertOffset += $childDepth;
       unset($childDepth);
    }
    

    在新方法中,将每个比较放在单独的行中。

    附:不要害怕方法名称太长。

    【讨论】:

    • 我给了这个+1,但我越想越意识到这只是将臃肿的if 条件移动到文件的另一部分。它看起来不错,但现在未来的程序员必须找到函数声明才能找出发生了什么。嗯……
    【解决方案2】:

    只需否定条件并跳过if 和else if 部分,因为这两个初始条件不执行任何操作...

    if (
         !($instructionObject->instruction=='nesting_grammar' && 
           $instructionObject->match=='>') 
        || !($instructionObject->instruction=='selector' 
            && is_object($this->instructions[$key+1]) 
            && $this->instructions[$key+1]->instruction == 'nesting_grammar' 
            && $this->instructions[$key+1]->match == '>')
     ) {
       $insertOffset += $childDepth;
       unset($childDepth);
     }
    

    【讨论】:

      【解决方案3】:

      不是直接回答你的问题,而是像这样的:

      if (my_check($instructionObject) || $instructionObject->instruction=='selector' && my_check($this->instructions[$key+1])) {
      } else {
         $insertOffset += $childDepth;
         unset($childDepth);
      }
      
      function my_check($obj) {
          return is_object($obj) && $obj->instruction == 'nesting_grammar' && $obj->match == '>';
      }
      

      -- 你基本上是在做同样的事情两次,是时候考虑一​​个函数了。

      【讨论】:

        【解决方案4】:

        就我个人而言,如果我要将检查跨越多行,我会将其布局类似于我布局 JavaScript 对象的方式;

        if (
            great big long check line goes in here &&
            another really long ugly check line goes in here too
        ) {
           // Do this code
        }
        else if (
            check 3 &&
            check 4
        ) {
            //Do this code
        }
        

        【讨论】:

          【解决方案5】:

          将子表达式拉出到变量中。伪例子:

          flibjit = FlibjitManager.FlibjitInstance(this);
          isFrob = 
              (flibjit.Froblocity >= FlibjitManager.FrobThreshold) &&   
              (flibjit.Type == FlibjitTypes.Frobby);
          
          if (isFrob) {
             // ...
          

          【讨论】:

          • 我喜欢您使用建议的变量名称的方法! :)
          猜你喜欢
          • 2016-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-04
          • 1970-01-01
          • 1970-01-01
          • 2020-11-18
          相关资源
          最近更新 更多